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> 密 码: <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.不是重复提交的情况
①:注册成功,点击后退,刷新原来的表单页面,不是重复提交
因为,在注册页面刷新,相当于重新注册一个新用户。