表单什么时候会出现重复提交

1.表单的重复提交

①:重复提交情况:在表单提交到一个Servlet,而servlet又通过请求转发的方式响应一个jsp(html),此时地址栏还是第一次请求servlet的地址栏,在响应页面刷新时,会出现重复提交。重定向不会

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

response.sendRedirect(request.getContextPath()+"/background/main.jsp");

②:在提交表单时,如果网速较差,可能会导致点击提交按钮多次,这种情况也会导致表单重复提交

解决方法:在提交之后,把按钮设置为不可以用(js)

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


③:表单提交成功以后,直接点击浏览器上回退按钮,不刷新页面,然后点击提交按钮再次提交表单

解决方法:在jsp中加入一个标记
reg.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>
<%
    //java代码
    //随机出现一个令牌,转成String,并且去除其中的“-”
    String uuid = UUID.randomUUID().toString().replace("-", "");
    // 把生成的令牌放到session域中
    session.setAttribute("token1", uuid);
%>
<body>
  
    <form action="regServlet" method="post">
        <input type="hidden" name="token" value="<%=uuid%>"/>
        用户名:<input type="text" name="name"><br>&nbsp;&nbsp;码: <input type="password" name="pwd"><br>
        <input type="submit" value="注册">
    </form>
    
</body>
</html>

RegServlet.java

package com.hpe.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        // 获取用户请求参数
        // 获取reg中token令牌,防止用户重复提交
        // 获取<input>标签中的令牌
        String token = request.getParameter("token");
        // 获取session中令牌
        String token1 = (String) request.getSession().getAttribute("token1");
        //两个令牌判断,相等的话:相当于注册成功,清除session中的令牌,
        //             因为注册成功之后,session中清空,两个令牌不相等,所以判断为重复提交
        if (token.equals(token1)) {
            System.out.println("注册成功");
            request.getSession().removeAttribute("token1");
            // 请求转发——一般用在request数据共享(setAttribute)
            // 会产生重复提交---为什么
            // 转发地址栏没变,还是regServlet,刷新一次相当于重新请求了一次regServlet,再执行了一次
            request.getRequestDispatcher("/index.jsp").forward(request, response);
        } else {
            System.out.println("注册失败,重复提交");
            request.getRequestDispatcher("/index.jsp").forward(request, response);
        }
        
        // 把参数赋值给实体类属性
        
        // 调用service方法
        
        // 判断是否注册成功
        
        
        
        
        
    }

}

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

2.不是重复提交的情况

①:注册成功,点击后退,刷新原来的表单页面,不是重复提交

因为,在注册页面刷新,相当于重新注册一个新用户。

posted @ 2019-09-19 09:31  专心搞开发  阅读(812)  评论(0编辑  收藏  举报