解决表单重复提交问题

问题背景:

由于用户或网络延迟原因,用户在提交表单时会多次点击提交,此时表单内容会被多次提交给服务器。这样会资源的浪费。亟待解决。

表单重复提交类型:

1. 提交完表单以后,不做其他操作,直接刷新页面,表单会提交多次。
产生原因:

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

2. 在提交表单时,如果网速较差,可能会导致点击提交按钮多次,这种情况也会导致表单重复提交。 产生原因: 提交按钮可以点击多次。 解决方案: 使提交按钮只能点击一次。JS代码实现
window.onload = function(){
		
					//获取按钮的对象
			var btn = document.getElementById("sub_btn");
					//为按钮绑定单击响应函数
					btn.onclick = function(){
						//点击以后使按钮不可用
						this.disabled=true;	
			//当将提交按钮设置为不可用时,会自动取消它的默认行为
						//手动提交表单
						this.parentNode.submit();	
					};	
				};

3. 表单提交成功以后,直接点击浏览器上回退按钮,不刷新页面,然后点击提交按钮再次提交表单。 产生原因: 因为服务器在处理请求时,不会检查是否为重复提交的请求。 解决方案: **使用一个token的机制。** - token就是令牌的意思。 - 服务器在处理请求之前先来检查浏览器的token。 - token由服务器来创建,并交给浏览器,浏览器在向服务器发送请求时需要带着这个token - 服务器处理请求前检查token是否正确,如果正确,则正常处理,否则返回一个错误页面 - 服务器所创建的token只能使用一次。 - token一般使用一个唯一的标识。 具体解决流程: 1、生成一个token ``` <% //在服务器中生成一个token(一次性的令牌) String token = UUID.randomUUID().toString();
//在服务中保存token
session.setAttribute("token", token);

%>

${requestScope.contextPath }

注册页面

用户名 ``` 2、在servlet中进行令牌的对比 ``` //获取浏览器持有的token String reqToken = request.getParameter("token");
	//获取session中保存的token
	String sessToken = (String) request.getSession().getAttribute("token");
	
	//将使用过的token从session中移除
	request.getSession().removeAttribute("token");
	
	//比较令牌是否一致
	if(reqToken != null && reqToken.equals(sessToken)){
		//令牌一致,处理请求
		//获取用户名
	String username = request.getParameter("username");
		
		//将用户信息插入进数据库
	System.out.println("已经将 "+username+" 插入进数据库!");
	
		//重定向到regist-success.jsp

response.sendRedirect(request.getContextPath()+"/form/regist-success.jsp");

	}else{
		
		//重复提交的请求,重定向到一个错误页面
		response.sendRedirect(request.getContextPath()+"/form/error.jsp");
	}
![token机制图解](https://img-blog.csdn.net/20170812110038735?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjUzNDM1NTc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
<hr/>

Strusts2框架防止表单重复提交(套路)
----------------------
1、我们直接在表单中使用<font color="red">&lt;s:token&gt;&lt;/s:token&gt;标签</font>,它可以自动在表单创建一个表单隐藏域,并生成一个随机的token,同时它也会将该token放入到session域中。
2、使用拦截器可以在请求到达action之前来替我们验证token值。
Struts2框架提供了两种token拦截器-----token和tokenSession:

> 这两个拦截器检查token的机制相同,检查请求参数中的token和Session中token是否一致检查完毕之后都会从session中移除token
> 					不同的是token 会在没通过验证时,将页面转到一个错误页面
> 					而tokenSession会继续转到action执行完毕以后的页面,但是action并不会执行

<font color="skyblue">token</font>
-token拦截器,会在检查token错误时,将请求转到result的name为invalid.token的结果。
- 使用token拦截器之前,需要先在action中引入token拦截器
					



/token-error.jsp


<font color="skyblue">tokenSession</font>
-tokenSession拦截器在发现表单重复提交以后,并不会转到错误页面,而是继续返回执行成功页面,但是它不会执行action的方法



/success.jsp
/token-error.jsp


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值