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

    感谢原文作者:LWJJJ
    原文地址:https://www.cnblogs.com/lwj-0923/p/7367517.html
    补充:https://www.cnblogs.com/SCAU_que/articles/2009458.html
    补充:https://www.cnblogs.com/xdp-gacl/p/3859416.html

    第一种情况:提交完表单以后,不做其他操作,直接刷新页面,表单会提交多次。

    -在servlet中写一句输出,用来判断是否提交多次

    System.out.println("已经插入");
    request.getRequestDispatcher("/login_success.jsp").forward(request, response);
    

    -这样的话,刷新多少次,就会在控制器显示多少个“已经插入”。
    在这里插入图片描述
    -根本原因:Servlet处理完请求以后,直接转发到目标页面,这样整个业务只发送了一次请求,那么当你在浏览器中点击刷新会一直都会刷新之前的请求。

    -解决方法:不用转发到另一页面,采用重定向的方式跳转到目标页面

    response.sendRedirect("/day0815-session/login_success.jsp");
    

    在这里插入图片描述
    第二种情况:在提交表单时,如果网速较差,可能会导致点击提交按钮多次,这种情况也会导致表单重复提交。

    -解决方法:点击提交按钮之后,使按钮不可用。通过js完成

    <script type="text/javascript">
        window.onload = function(){ 
            //获取按钮的对象
            var btn = document.getElementById("btn");
            //为按钮绑定单击响应函数
            btn.onclick = function(){     
                //点击以后使按钮不可用
                this.disabled=true;  
                //当将提交按钮设置为不可用时,会自动取消它的默认行为
                //手动提交表单
                this.parentNode.submit();  
            };
        };
    </script>
     
    <form action="${pageContext.request.contextPath }/SessionServlet" >
    user:<input type="text" name="username">
    password<input type="password" name="pwd">
    <input type="submit" value="提交" id="btn"> 
    </form>
    

    -注意“提交”按钮,此时已经不可按!
    在这里插入图片描述
    第三种情况:表单提交成功以后,直接点击浏览器上回退按钮,不刷新页面,然后点击提交按钮再次提交表单。

    -根本原因:因为服务器在处理请求时,不会检查是否为重复提交的请求。

    -解决方案:
    使用一个token的机制
    - token就是令牌的意思
    - 服务器在处理请求之前先来检查浏览器的token
    - token由服务器来创建,并交给浏览器,浏览器在向服务器发送请求时需要带着这个token
    - 服务器处理请求前检查token是否正确,如果正确,则正常处理,否则返回一个错误页面
    - 服务器所创建的token只能使用一次
    - token一般使用一个唯一的标识

    -在jsp页面,获取uuid作为token

    - UUID:32位字符串,通常作为对象或者表的唯一标识,根据机器码和时间戳(从1970年1月1日开始到现在)生成。

    <%
        String uuid = UUID.randomUUID().toString();
        session.setAttribute("uuid", uuid);
    %>
    ${errormsg }
    <form action="${pageContext.request.contextPath }/SessionServlet" >
      <input type="text" name="uuid" value="<%=uuid %>"/>
      user:<input type="text" name="username">
      password<input type="password" name="pwd">
      <input type="submit" value="提交" ">
    </form>
    

    -在servlet页面

    String reqUUID = request.getParameter("uuid");
    HttpSession session = request.getSession();
    String sessUUID = (String) session.getAttribute("uuid");
    session.removeAttribute("uuid");
         
    if(reqUUID.equals(sessUUID)){
        response.sendRedirect(request.getContextPath()+"/login_success.jsp");
        System.out.println("已经插入");
    }else{
        request.setAttribute("errormsg", "重复登陆");
        request.getRequestDispatcher("/3.jsp").forward(request, response);
    }
    

    -表单重复提交的危害:
    - 向数据库中插入大量的重复且没有意义的数据,占用服务器的资源
    - 处理请求服务器并没有检查请求是否为重复的请求,导致恶意的攻击

  • 相关阅读:
    CSS中position小解
    position
    mac默认安装postgresql, 如何让postgresql可以远程访问
    The data directory was initialized by PostgreSQL version 9.6, which is not compatible with this version 10.0.
    active admin gem error
    psql 无法添加超级用户
    ubuntu 15.04 安装Balsamiq Mockups 3
    Rails html 写public里图片的路径
    rails c 历史命令
    undefined local variable or method `per' for []:ActiveRecord::Relation
  • 原文地址:https://www.cnblogs.com/tfxz/p/12621513.html
Copyright © 2011-2022 走看看