赞
踩
页面刷新重复提交请求这个问题在Web开发中很常见。在很多时候我们都忽略了这个问题。
那么这个问题的如何触发的呢?
一般无非就是你按F5或者在页面鼠标右键点击刷新。可能会触发这个问题。
那么为什么会出现这种问题呢。这个是浏览器的原因。浏览器中有一个history对象,history中有一个State。当我们发送请求的时候,会将请求存入history的State中。这个State的结构就像一个栈。拥有着后进先出的特性。也正是因为这个对象,我们才能能够在浏览器中执行后退,前进等操作。
但是你比方说,如果我们的上一次请求是往数据库中insert一条语句。那么不断刷新页面,就会不断去执行这个Insert逻辑。所以一般我们对数据库进行修改操作后,会重定向当前页面,那么重定向的这个url就会存入State的栈顶了。这时候你再怎么刷新页面,按F5都只是重定向当前页面,而不是insert了。因为history对象的State栈顶元素被替换成了你重定向的那个请求。
最简单的方法就是禁用F5按键和鼠标右键刷新事件。这个在js层面就可以做的。但这种方式也太粗暴了,不推荐使用
那么这个问题如何解决呢?
核心思想就是Post/Redirect/Get模式
在html5中新增了两个方法,一个是replaceState,另外一个是pushState。
前面我们已经知道,每当我们发送一次请求,就会往State中存入一条记录。这两个方法能够修改history中State的值。也就是说你可以手动替换栈顶元素。
在页面加载的时候执行如下代码
if(replaceState){
history.replaceState(null,null,'当前页面路径');
}
更多repalceState的详细方法大家可以自行去了解一下。
Token是什么意思呢?字面意思就是令牌。先来说一下它的实现方式。这种方式比较适合前端页面是JSP页面的。如果是html也可以使用。但是这种方式有一个限制。那就是你发送请求页面发生了跳转。一般应用于那种页面发生跳转的场景。
如果说发送请求后,你的页面依然是在当前页面。那么这种方式是不可行的。
这里以前端页面为JSP为例,因为JSP中可以写Java代码,获取Session较为方便,当然了,HTML也能够获取Seession,但是稍微复杂一点。感兴趣的可以自己搜一下。
首先,我们先生成一个随机字符串,将这个字符串存入Session中和表单隐藏域中。然后在前端控制层,也就是Controller层或者Action层。
前端JSP页面加上如下代码
<%
String token=UUID.getId();
request.getSession.SetAttribute("tocken",token);
%>
<html>
<form>
<input type='hidden' name='token' value='<%=token%>'/>
</form>
</html>
Controller层代码
String token=(String) req.getSession().getAttribute("token");
String f = req.getParameter("token");
if(f.equals(token)){
//说明是表单a提交的请求,执行insert逻辑
insert();
req.getSession().removeAttribute("token");
}else{
//重定向当前页面
}
原理是什么呢?当第一次插入逻辑执行成功后,删除session中的值,这个时候你刷新页面重新发送请求session中的token值是null。因此他就会走else逻辑。这个时候你重定向当前页面就好了。
ajax是一种异步刷新的技术。非常的方便。个人觉得这种方式是最好的。无论你发送请求后是在当前页面还是跳转了页面。这种方式都是比较不错的。但前提是你比较熟悉ajax的使用。
$.ajax{
url:
data:
datatype:
success(data){
//假设你执行的是一个insert操作,现在返回了一个标志位成功
if(data==true){
//从定向页面,根据场景可以是当前页面也可以是其他页面
location.herf="";
}
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。