情况一:网络延迟,在网络延迟时间内,频繁的提交表单
解决方案:
只能提交一次,监控表单的提交事件,通过一个boolean类型的变量来区分已经点击过还是没有点击,如果已经点击过,表单就不提交,没有点击过再提交
//创建一个变量 false代表没有点击过,true代表已经点击过 var flag=false; function formSubmit() { if(!flag){ //取反值为false //提交过一次,修改标识 flag=true; return true; }else { return false; } }
这样提交过一次后就会一直进else块,return false;
情况二:重新加载或者后退页面
解决方案:
在加载页面的时候,创建一个Token令牌(当作一个标识) ,保存到session当中,然后在表单提交的时候将令牌一起提交
后台Servlet去判断session当中的令牌和表单提交的令牌是否相等,如果相等代表正常提交(并且将session清空),如果不相等,代表非正常提交
表单:
<form action="FormServlet" onsubmit="return formSubmit()" method="post"> <%--页面加载时将生成的令牌保存在这个隐藏域中--%> <input type="hidden" id="hiddenToken" name="formToken"/> <input type="text" name="username"/> <input type="submit" value="提交"/> </form>
script:
//创建一个变量 false代表没有点击过,true代表已经点击过 var flag=false; function formSubmit() { if(!flag){ //取反值为false //提交过一次,修改标识 flag=true; return true; }else { return false; } } $(function () { //生成令牌 $.ajax({ url:"TokenServlet", type:"POST", success:function (token) { $("#hiddenToken").val(token); } }) })
TokenServlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //生成令牌 String token = UUID.randomUUID().toString(); //令牌保存到session当中 request.getSession().setAttribute("sessionToken",token); //响应回页面给隐藏域 response.getWriter().write(token); }
FormServlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //验证令牌 //获取页面提交的隐藏域数据 String formToken = request.getParameter("formToken"); //获取Session中的Token String sessionToken = (String)request.getSession().getAttribute("sessionToken"); //如果页面中获取的和session中不一致,代表已经提交过了,不要重复提交 if(!formToken.equals(sessionToken)){ response.getWriter().write("不要重复提交~"); return; } //不进if代表是第一次提交 //接收数据 String username = request.getParameter("username"); System.out.println("接收的数据为:"+username); //必须将token清空,不然永远是一致的 request.getSession().removeAttribute("sessionToken"); try { //模拟网络延迟 Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } //返回数据 response.getWriter().write("success"); }
执行效果:
第一次正确提交返回数据
后台:
刷新网页后提示: