引入

看一个重复提交表单的例子

F12可以看到,请求体中的参数在刷新页面之后仍然保留,因此每一次刷新页面,都会把现有的请求体中的表单数据提交一次到服务器,而接收的页面还是insert.jsp,于是造成了重复提交表单,又新增了一条相同的数据。

解决方式:在servlet中,使用重定向(两次请求),而非请求转发(一次请求),可以防止表单重复提交。

下面,我们来看重复提交表单的三种情况、解决方式。


第一种情况

第一种情况:提交完表单以后,不做其他操作,直接刷新页面,表单会提交多次。

在servlet中写一句输出,用来判断是否提交多次

System.out.println("已经插入");
request.getRequestDispatcher("/login_success.jsp").forward(request, response);

这样的话,刷新多少次,就会在控制器显示多少个“已经插入”。

根本原因:Servlet处理完请求以后,直接转发到目标页面,这样整个业务只发送了一次请求,那么当你在浏览器中点击刷新会一直都会刷新之前的请求。

解决方法:不用转发到另一页面,采用重定向的方式跳转到目标页面

response.sendRedirect("/day0815-session/login_success.jsp");

第二种情况

第二种情况:在提交表单时,如果网速较差,可能会导致点击提交按钮多次,这种情况也会导致表单重复提交。

解决方法:点击提交按钮之后,使按钮不可用。通过js完成

<script type="text/javascript">window.onload = function(){ //获取按钮的对象var btn = document.getElementById("btn");//为按钮绑定单击响应函数btn.onclick = function(){     //点击以后使按钮不可用this.disabled=true;  //当将提交按钮设置为不可用时,会自动取消它的默认行为//手动提交表单this.parentNode.submit();  };};
</script>
<br>
<br><form action="${pageContext.request.contextPath }/SessionServlet" ><br>user:<input type="text" name="username"><br>password<input type="password" name="pwd"><br><input type="submit" value="提交" id="btn">
<br></form>

注意“提交”按钮,此时已经不可按!


第三种情况

第三种情况:表单提交成功以后,直接点击浏览器上回退按钮,不刷新页面,然后点击提交按钮再次提交表单。

-根本原因:因为服务器在处理请求时,不会检查是否为重复提交的请求。

解决方案:
使用一个token的机制
- token就是令牌的意思
- 服务器在处理请求之前先来检查浏览器的token
- token由服务器来创建,并交给浏览器,浏览器在向服务器发送请求时需要带着这个token
- 服务器处理请求前检查token是否正确,如果正确,则正常处理,否则返回一个错误页面
- 服务器所创建的token只能使用一次
- token一般使用一个唯一的标识

在jsp页面,获取uuid作为token

-UUID:32位字符串,通常作为对象或者表的唯一标识,根据机器码和时间戳(从1970年1月1日开始到现在)生成。
  
jsp

<%String uuid = UUID.randomUUID().toString();session.setAttribute("uuid", uuid);
%>
<br>${errormsg }<br><form action="${pageContext.request.contextPath }/SessionServlet" ><br>  
<input type="text" name="uuid" value="<%=uuid %>"/><br>  
user:<input type="text" name="username"><br>  
password<input type="password" name="pwd"><br>  
<input type="submit" value="提交" "><br></form>

servlet

String reqUUID = request.getParameter("uuid");
HttpSession session = request.getSession();
String sessUUID = (String) session.getAttribute("uuid");
session.removeAttribute("uuid");if(reqUUID.equals(sessUUID)){response.sendRedirect(request.getContextPath()+"/login_success.jsp");System.out.println("已经插入");
}else{request.setAttribute("errormsg", "重复登陆");request.getRequestDispatcher("/3.jsp").forward(request, response);
}

表单重复提交的危害:
- 向数据库中插入大量的重复且没有意义的数据,占用服务器的资源
- 处理请求服务器并没有检查请求是否为重复的请求,导致恶意的攻击

【重复提交表单】表单重复提交的三种情况,解决办法相关推荐

  1. mysql002多表查询.on链接分为三种情况,左链接,右链接,全链接

    -- on链接(最实用),分为三种情况,左链接,右链接,全链接 -- 左外链接,左表全部显示,如果匹配不到右表的内容使用null代替. SELECT * FROM emp e LEFT JOIN de ...

  2. fullpage在vue单页面当中使用会出现的问题以及解决办法

    fullpage在vue单页面当中使用会出现的问题以及解决办法 参考文章: (1)fullpage在vue单页面当中使用会出现的问题以及解决办法 (2)https://www.cnblogs.com/ ...

  3. 使用注册表编辑win10鼠标右键菜单,详细解释(右键文件夹、文件以及右键空白区域下三种情况)

    本文参考Stackoverflow的解答How add context menu item to Windows Explorer for folders win10鼠标右键菜单管理:右键文件夹.文件 ...

  4. 表单设置 disabled 后无法传值到后台的解决办法

    提交 from 表单时,如果input字段设为disabled,该字段是无法正常提交给后台的. <input type="text" name="name" ...

  5. Oracle数据库重复数据删除的三种情况

    在对数据库进行操作过程中我们可能会遇到这种情况,表中的数据可能重复出现,使我们对数据库的操作过程中带来很多的不便,那么怎么删除这些重复没有用的数据呢? 重复数据删除技术可以提供更大的备份容量,实现更长 ...

  6. Azure数据仓库表中的数据经常使用的三种分布策略(hash、round_robin 或 replicated)简介

    目录 (一)前言 (二)基础概念 1. Azure Synapse Analytics概念 2. Synapse SQL 体系结构组件 3. Azure 存储 4. 控制节点 5. 计算节点 6. 数 ...

  7. SQL:将查询结果插入到另一个表的三种情况

    一:如果要插入目标表不存在: select * into 目标表 from 表 where ... 二:如果要插入目标表已经存在: insert into 目的表 select * from 表 wh ...

  8. ITSM常见问题之:自动指派工单给对应的技术员的三种简单方法

    假设在某个月末,发工资的员工无法登录到工资支付应用程序,为了解决这个问题,他向IT帮助台发送了一封电子邮件,即创建了一个工单.不巧的是,这时服务台协调员并不在公司,于是工单一直处于未指派状态,直到服务 ...

  9. 字符映射表没有所有字体(专用字符),以及显示空白的解决办法

    这是两个问题,分开解答处理一下 一.字符映射表没有所有字体(专用字符):这个一般是注册表的问题,需要将HKEY_CURRENT_USER\EUDC\936   中  SystemDefaultEUDC ...

最新文章

  1. MySQL番外篇:一条SQL查询语句是如何执行的?
  2. 【133天】尚学堂高淇Java300集视频精华笔记(71-72)
  3. python wxpython backend wxagg_[宜配屋]听图阁
  4. 金融系统中正确的金额计算及存储方式
  5. java开发展望怎么写_Java开发趋势:2019年展望
  6. java1.5以后新增的特性_jdk1.5之后的一些新特性
  7. Debugging--the practice of programming
  8. About Me Leo是谁
  9. Google Chrome 开发进度 官方Blog
  10. 还怕没女朋友吗?用python做个表白吧
  11. 小米商城php源码安装教程,搭建小米商城 框架div
  12. 4种JavaScript中获取HTML元素的方式
  13. adb工具的使用方法详解
  14. Segmentation简记5-AuxNet: Auxiliary tasks enhanced Semantic Segmentation for Automated Driving
  15. php dingo和jwt,Laravel5.5+dingo+JWT 开发后台 API
  16. 信用卡号码的解析(转)
  17. CTF中出现的各种字符/密码总结
  18. 面试官问:代理模式和装饰者模式有啥区别
  19. 毛边效果 html,html – 是否有可能在图片的边缘上产生撕裂的纸张效果
  20. 算法之牛顿法求平方根+立方根

热门文章

  1. 微分方程_微分方程 | 线性微分方程组的求解(上)
  2. SPOJ1812(后缀自动机求n个串的最长公共子串)
  3. input()与raw_input()
  4. Miller-Rabin素数测试
  5. GetLongPathName和GetShortPathName函数
  6. 剖析入侵技术 嗅探软件了解
  7. QUIC/HTTP2相关资料整理
  8. python获取cookies
  9. Netty学习笔记(六)Pipeline的传播机制
  10. 优化 Golang 分布式行情推送的性能瓶颈