同一个表单、同样的数据,如果多次提交,就会给服务器造成不必要的压力,同时也会向数据库中保存垃圾数据。表单的重复提交分为三种
一.在转发的情况下,表单提交成功后,反复刷新成功页面,就会导致表单的重复提交。
解决方案:我们改用重定向response.sendRedirect()的方式进入另一个页面。放入request域中的数据改为放在session域中,这样就不会出现表单的重复提交.
二.在网速很慢的情况下,我们多次点击重复按钮
解决方案:设置提交按钮只点击一次。我们先找到提交的按钮,然后设置disable属性为true,这样当点击按钮时,按钮就会变为灰色的,不能再使用.我们最后还要必须手动提交一下表单。因为在不同的浏览器上,不加手动提交,会有不同的效果.我们用JS写该功能.
$(function(){
//给提交按钮绑定单击事件
$("#sub").click(function(){
//设置提交按钮不可用
$(this).attr("disabled",true);
//手动提交表单
$("form").submit();
});
});
三.表单提交成功后,点击浏览器的返回按钮,在不刷新的情况下再次提交表单.
解决方案:使用token(标记)
使用步骤:
1.在服务器段通过UUID生成一个唯一的字符串token,将token保存到session中
2.在表单中设置一个隐藏域,把token放到隐藏域中,对着表单提交到服务器上.
3.在服务器中获取表单中的隐藏域中的token,然后在吧session中的token对比。
如果相等,正常处理请求
若不相等,表单重复提交
4.正常如理后,一定要删除session中的token
我做了一下简单的实例
JSP代码:
<body>
<%
String token = UUID.randomUUID().toString();
session.setAttribute("sessToken", token);
%>
<form action="RepeatServlet" method="post">
<input type="hidden" name="reqToken" value="<%=token %>"/>
用户名:<input type="text" name="username"/><br><br>
密 码:<input type="password" name="password"/>
<input type="submit" value="提交"/>
</form>
</body>
Servlet代码:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String reqToken = request.getParameter("reqToken");
System.out.println("reqToken:"+reqToken);
HttpSession session = request.getSession();
String sessToken = (String) session.getAttribute("sessToken");
System.out.println("sessToken:"+sessToken);
if(sessToken!=null && sessToken.equals(reqToken)){
System.out.println("表单提交了...");
session.removeAttribute("sessToken");
response.sendRedirect(request.getContextPath()+"/success.jsp");
}else{
//证明重复提交表单
//重定向到错误页面
response.sendRedirect(request.getContextPath()+"/erroe.jsp");
}
}
第一提交时,打印结果:
reqToken:213c0f56-7805-4626-a0f3-6c279f971db7
sessToken:213c0f56-7805-4626-a0f3-6c279f971db7
表单提交了...
重复提交时,打印结果,跳到错误页面
reqToken:213c0f56-7805-4626-a0f3-6c279f971db7
sessToken:null
此时两个值不相等,说明表单重复提交,可以做想要的操作。