JavaWeb课程系列
3.表单重复提交问题
3.1什么是表单重复提交?
同一个表单中的数据内容多次提交到服务器。
危害:
服务器重复处理信息,负担加重。
如果是保存数据可能导致保存多份相同数据。
3.2几种重复提交
1)提交完表单后,直接刷新页面,会再次提交。
- 根本原因:Servlet处理完请求以后,直接转发到目标页面。
- 这样整一个业务,只发送了一次请求,那么当你在浏览器中点击刷新按钮或者狂按f5 会一直都会刷新之前的请求
解决方案:使用重定向跳转到目标页面
2)提交表单后,由于网速差等原因,服务器还未返回结果,连续点击提交按钮,会重 复提交。
- 根本原因:按钮可以多次点击
- 解决方案:通过js,使得按钮只能提交一次。
$(“#form1”).submit(function(){
$(“#sub_btn”).prop(“disabled”,true);
})
3)表单提交后,点击浏览器回退按钮,不刷新页面,点击提交按钮再次提交表单
- 根本原因:服务器并不能识别请求是否重复。
- 解决方案:使用token机制。
1、页面生成时,产生一个唯一的token值。将此值放入session
2、表单提交时,带上这个token值。
3、服务端验证token值存在,则提交表单,然后移除此值。
验证token不存在,说明是之前验证过一次被移除了,所以是重复请求。不予 处理
原理:
代码:
- jsp页面
<% String token = System.currentTimeMillis() + ""; request.getSession().setAttribute(token, ""); %> <div> <h1>测试表单重复提交</h1> <form action="login" method="get"> 用户名:<input name="username" type="text"/> 密码:<input name="password" type="password"> <input name="token" value="<%=token%>"> <input type="submit"> </form> <hr> </div> |
- Servlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); String token = request.getParameter("token"); Object attribute = session.getAttribute(token); response.setContentType("text/html;charset=UTF-8"); if(attribute!=null){ session.removeAttribute(token); response.getWriter().write("请求成功!"); }else{ response.getWriter().write("请不要重复请求!"); } } |
其实防止重复提交的核心就是让服务器有一个字段能来识别此次请求是否已经执行。
这个字段需要页面传递过来,因为只要回退回去的页面,字段都是一致的。不会变化,通过这个特性我们想到了token机制来防止重复提交