表单重复提交的解决方法
第一种情况:提交完表单以后,不做其他操作,直接刷新页面,表单会提交多次。
- 在servlet中写一句输出,用来判断是否提交多次
1
2
|
System.out.println( "已经插入" );
request.getRequestDispatcher( "/login_success.jsp" ).forward(request,
response);
|
- 这样的话,刷新多少次,就会在控制器显示多少个“已经插入”。
- 根本原因:Servlet处理完请求以后,直接转发到目标页面,这样整个业务只发送了一次请求,那么当你在浏览器中点击刷新会一直都会刷新之前的请求。
- 解决方法:不用转发到另一页面,采用重定向的方式跳转到目标页面
1
|
response.sendRedirect( "/day0815-session/login_success.jsp" );
|
第二种情况:在提交表单时,如果网速较差,可能会导致点击提交按钮多次,这种情况也会导致表单重复提交。
- 解决方法:点击提交按钮之后,使按钮不可用。通过js完成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<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日开始到现在)生成。
1
2
3
4
5
6
7
8
9
10
11
|
<%
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页面
1
2
3
4
5
6
7
8
9
10
11
12
|
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);
}
|
- 表单重复提交的危害:
- 向数据库中插入大量的重复且没有意义的数据,占用服务器的资源
- 处理请求服务器并没有检查请求是否为重复的请求,导致恶意的攻击