防止表单重复提交的三种方式

表单的重复提交

  • 同一个表单中的内容多次提交到服务器中。

  • 第一种情况:
    提交完表单以后,不做其他操作,直接刷新页面,表单会提交多次。
    - 这种情况产生的根本原因是,Servlet处理完请求以后,直接转发到目标页面。
    - 这样整一个业务,只发送了一次请求,那么当你在浏览器中点击刷新按钮或者狂按f5会一直都会刷新之前的请求
    -解决方案:
    使用重定向跳转到目标页面

  • 第二种情况:
    在提交表单时,如果网速较差,可能会导致点击提交按钮多次,这种情况也会导致表单重复提交。
    - 产生的原因:是因为咱们的提交按钮可以点击多次。
    - 解决方案:
    使提交按钮只能点击一次。这事咱们得通过js来完成。

    window.onload = function(){

                    //获取按钮的对象
                    var btn = document.getElementById("sub_btn");
                    //为按钮绑定单击响应函数
                    btn.onclick = function(){

                        //点击以后使按钮不可用
                        this.disabled=true;

                        //当将提交按钮设置为不可用时,会自动取消它的默认行为
                        //手动提交表单
                        this.parentNode.submit();

                    };

                };
  • 第三种情况:
    表单提交成功以后,直接点击浏览器上回退按钮,不刷新页面,然后点击提交按钮再次提交表单。
    - 产生的原因:因为服务器在处理请求时,不会检查是否为重复提交的请求。
    - 解决方案:使用一个token的机制。
    - token就是令牌的意思。
    - 服务器在处理请求之前先来检查浏览器的token。
    - token由服务器来创建,并交给浏览器,浏览器在向服务器发送请求时需要带着这个token
    - 服务器处理请求前检查token是否正确,如果正确,则正常处理,否则返回一个错误页面
    - 服务器所创建的token只能使用一次。
    - token一般使用一个唯一的标识。

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

在index.jsp页面中:

<%@page import="java.util.UUID"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<% 
    String id=UUID.randomUUID().toString();//新建id随机数,此处id即为令牌
    session.setAttribute("id", id);
    System.out.println(id);
    %>
<form action="/Session/SessionServlet" method="get">
    <input type="text" name="requUUID" value=${id }>
    <input type="text" name="user" >
    <input type="text" name="password">
    <input type="submit">
</form>
</body>
</html>

在SessionServlet中:

@WebServlet("/SessionServlet")
public class SessionServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;


    public SessionServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        sessService service=new sessService();
        HttpSession session=request.getSession();
        String sessUUID=(String) session.getAttribute("id");//获取session中的id
        String requUUID=request.getParameter("requUUID");//获取表单隐藏中的requUUID
        String user=request.getParameter("user");
        String pwd=request.getParameter("password");
        session.removeAttribute("id");    

        if(sessUUID!=null){
            try {
                Thread.sleep(1000*4);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if (sessUUID.equals(requUUID)) {
                User user2=service.selectUser(user,pwd);
                if(user2!=null){
                    request.setAttribute("user", user2);
                    System.out.println(user2);
                    System.out.println("登陆成功!");
                    /*response.sendRedirect(request.getContextPath()+"/2.jsp");*/
                    request.getRequestDispatcher("/2.jsp").forward(request, response);;
                }
                else {
                    System.out.println("登陆失败!");
                }

            }
            else {
                System.out.println("请不要重复登陆");
                System.out.println("session的id为:"+sessUUID);
                System.out.println("request的id为:"+requUUID);
            }
        }
        else {
            System.out.println("请不要重复登陆");
        }

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值