为什么会出现表单重复提交问题
1.网络延迟的情况下用户多次点击提交按钮导致表单重复提交;
2.用户提交表单时,点击浏览器【刷新】按钮导致表单重复提交,就是把浏览器上次做的事情再做一次;
3.用户提交表单后,点击浏览器【后退】按钮回退到表单页面后进行再次提交;
表单重复提交会导致的问题
能够造成很多脏数据;
解决办法
前端解决方法:只能提交一次,监控表单的提交事件,通过boolean类型的变量来区分已经点击过一次还是没有点击,如果已经点击过一次,表单就不提交,如果没有提交,表单则会提交。
后端解决方法:在访问提交页面的时候,创建一个token令牌(当作一个标志),保存到session中,然后在表单提交的时候将令牌一起提交给后台,让后台判断session中的token令牌和表单提交的令牌是否一致,如果一致代表正常提交,然后将session中的数据清空,如果不相等,代表非正常提交。
代码展示
前端代码:
<%--
Created by IntelliJ IDEA.
User: wn
Date: 2020/2/3
Time: 16:59
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>表单重复提交</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script>
var isFlag=false; //表单是否已经提交标识,false代表没有点击过,true代表点击过
function submitFlag() {
if (!isFlag){ //取反值
isFlag=true;
return true;
} else{
return false;
}
}
//token令牌
$(function () {
//生成令牌
$.ajax({
url:"tokenServlet",
type:"POST",
success:function (token) {
$("#token").val(token);
}
})
})
</script>
</head>
<body>
<form action="submitServlet" onsubmit="return submitFlag()" method="post">
<input type="hidden" id="token" name="token" />
用户名:<input type="text" name="username" />
<button type="submit">提交</button>
</form>
</body>
</html>
token类:
package com.wn;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;
@WebServlet("/tokenServlet")
public class TokenServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//生成令牌
String token = UUID.randomUUID().toString();
//令牌保存到session当中
req.getSession().setAttribute("token",token);
//将生成的令牌响应给页面
resp.getWriter().write(token);
}
}
后端代码:
package com.wn;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/submitServlet")
public class SubmitServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取页面中的token令牌
String token = req.getParameter("token");
//获取session中的token令牌
String token1 = (String) req.getSession().getAttribute("token");
//将页面获取的token令牌与session中的token令牌比较是否一致
//如果不一致代表补不能重复提交,如果一致则走下面的操作
if (!token.equals(token1)){
resp.setContentType("text/html;charset=utf-8");
resp.setCharacterEncoding("UTF-8");
resp.getWriter().write("数据不能重复提交error!");
return;
}
//接收页面的username属性值
String username = new String (req.getParameter("username").getBytes("ISO-8859-1"),"UTF-8");
System.out.println("数据:"+username);
// //请求session中的值
req.getSession().removeAttribute("token");
try {
//模拟网络延迟
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//响应数据
resp.getWriter().write("success");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
}