zoukankan      html  css  js  c++  java
  • 解决表单重复提交

    为什么会出现表单重复提交问题

      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);
        }
    }
  • 相关阅读:
    Golang里边的map变量是什么?
    Golang map的底层实现
    方法和函数的区别
    Golang 对 对象和指针 的理解
    React 部分
    前端开发概述、html、css基础
    服务器核心知识
    常用模块8.7
    2017.8.2迭代器和生成器
    2017.7.18可变/不可变类型,符号运算及其流程控制
  • 原文地址:https://www.cnblogs.com/wnwn/p/12268906.html
Copyright © 2011-2022 走看看