当前位置:   article > 正文

页面刷新重复提交请求如何解决_h5刷新重提交

h5刷新重提交

前言

页面刷新重复提交请求这个问题在Web开发中很常见。在很多时候我们都忽略了这个问题。

那么这个问题的如何触发的呢?
一般无非就是你按F5或者在页面鼠标右键点击刷新。可能会触发这个问题。
那么为什么会出现这种问题呢。这个是浏览器的原因。浏览器中有一个history对象,history中有一个State。当我们发送请求的时候,会将请求存入history的State中。这个State的结构就像一个栈。拥有着后进先出的特性。也正是因为这个对象,我们才能能够在浏览器中执行后退,前进等操作。

但是你比方说,如果我们的上一次请求是往数据库中insert一条语句。那么不断刷新页面,就会不断去执行这个Insert逻辑。所以一般我们对数据库进行修改操作后,会重定向当前页面,那么重定向的这个url就会存入State的栈顶了。这时候你再怎么刷新页面,按F5都只是重定向当前页面,而不是insert了。因为history对象的State栈顶元素被替换成了你重定向的那个请求。
在这里插入图片描述

最简单的方法就是禁用F5按键和鼠标右键刷新事件。这个在js层面就可以做的。但这种方式也太粗暴了,不推荐使用

那么这个问题如何解决呢?
核心思想就是Post/Redirect/Get模式

方法一:使用html5的新特性

在html5中新增了两个方法,一个是replaceState,另外一个是pushState。
前面我们已经知道,每当我们发送一次请求,就会往State中存入一条记录。这两个方法能够修改history中State的值。也就是说你可以手动替换栈顶元素。

  • replaceState:顾名思义是将栈顶的State进行替换
  • pushState:是往栈里面添加一条请求
    当你做插入操作后,用该方法替换State的值为查询逻辑。那么你刷新页面,也就不会提交请求了。
    但是这种方式有缺陷。使用这种方式必须要确认你所使用浏览器版本是支持这个html5新特性的。否则这种方法是无效的。
    网上提供了一些方法,让低版本的浏览器也能使用这两个方法。在界面导入history.js脚本。但是这种方法并不好用。不一定能生效。

在页面加载的时候执行如下代码

if(replaceState){
  history.replaceState(null,null,'当前页面路径');
}
  • 1
  • 2
  • 3

更多repalceState的详细方法大家可以自行去了解一下。

方法二:使用Token

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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{
               //重定向当前页面  
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

原理是什么呢?当第一次插入逻辑执行成功后,删除session中的值,这个时候你刷新页面重新发送请求session中的token值是null。因此他就会走else逻辑。这个时候你重定向当前页面就好了。

方法三:使用ajax

ajax是一种异步刷新的技术。非常的方便。个人觉得这种方式是最好的。无论你发送请求后是在当前页面还是跳转了页面。这种方式都是比较不错的。但前提是你比较熟悉ajax的使用。

$.ajax{
  url:
  data:
  datatype:
  success(data){
     //假设你执行的是一个insert操作,现在返回了一个标志位成功
     if(data==true){
        //从定向页面,根据场景可以是当前页面也可以是其他页面
        location.herf="";
     }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/234473?site
推荐阅读
相关标签
  

闽ICP备14008679号