资讯专栏INFORMATION COLUMN

Web项目如何防止客户端重复发送请求

sewerganger / 794人阅读

摘要:在项目中,有一些请求或操作会对数据产生影响比如新增删除更新,针对这类请求一般都需要做一些保护,以防止用户有意或无意的重复发起这样的请求导致的数据错乱。本文总结了一些防止客户端重复发送请求的方法。

在Web项目中,有一些请求或操作会对数据产生影响(比如新增、删除、更新),针对这类请求一般都需要做一些保护,以防止用户有意或无意的重复发起这样的请求导致的数据错乱。

本文总结了一些防止客户端重复发送请求的方法。

方法一:JS监听Form的onsubmit事件

在经典场景下,浏览器通过Form发送请求。因此只需要在Form onsubmit时将Submit按钮disable,就能够防止用户双击导致的重复请求(这种问题一般发生在年纪大的用户身上,他们分不清单击和双击)。

但是随着前端的发展,Form以外的请求方式也越来越多,比如利用各种前端框架(Vue、AngularJs、Backbone等)写的App,他们更多的采用的是ajax的方式和后端交互。那么前端开发人员必须在开发时针对每个代表发起请求的UI元素做处理,像Form一样,在发起请求的时候把相关UI元素禁用掉。

而有些交互方式则可能连代表发起请求的UI元素都没有,比如Segmentfault的markdown编辑器就是在一边输入的时候一边保存的。那么这时就需要前端代码采用其他手段来控制重复请求的发生。

优点:

不需要后端写代码

缺点:

不存在统一的解决方案,必须针对每种情况写处理代码

无法控制浏览器刷新发起的重复请求

前端开发人员忘记写相关代码

无法控制恶意的重复请求,比如绕过浏览器直接发起

方法二:Http Status Code 302(后端重定向)

服务端采用重定向的方式,防止用户刷新浏览器发出重复请求。这是比较经典的后端控制重复请求的方式,因为一旦重定向成功后,用户刷新浏览器所刷新的是那个重定向地址,而不是数据操作地址。

优点:

不需要写前端代码

缺点:

在还未响应302之前,所发起的重复请求,比如:用户快速的双击、刷新浏览器

在某些前端程序里(比如SPA),不能使用重定向

后端开发人员忘记写相关代码

无法控制恶意的重复请求,比如绕过浏览器直接发起

方法三:结合方法一和方法二

结合方法一和方法二的话倒是可以解决大部分问题,但是解决不了以下问题:

在还未响应302之前,用户刷新浏览器导致的重复请求

有些场景下压根不能使用重定向

前、后端开发人员忘记写相关代码

无法控制恶意的重复请求,比如绕过浏览器直接发起

方法四:token方式

token的流程是这样的:

在浏览器发送请求前,先到服务端索要token

浏览器发送请求时,将token一并提交

服务端检查请求是否携带token、token是否有效(比如是否正确、是否过期)。如果不正确则响应失败;如果正确则销毁token,继续业务逻辑。

关键点在于:

每个token都是一次性且有过期时间的,能够防止token前端代码bug造成的重复利用和无限利用。

服务器要求请求必须携带token,能够避免前端开发人员漏写相关代码。

那么token是以怎样的形式传输的呢?我认为有以下两种方式:

Cookie

推荐使用这种方式,因为浏览器每次都会将cookie携带在请求里一并发出,所以前端发送请求的代码都不需要修改,只要在发送请求前问服务器拿token就行了。

比如在进入Form页面时,服务器将token以cookie的形式一并携带在响应中,那么前端Form提交时,就会将cookie一并携带在请求中,前端的代码一点都不需要修改。

json

前端发起ajax请求像后端拿token,后端以json的形式返回token,前端发送请求时将token携带在请求中,后端检验。

这种方式比Cookie稍微麻烦的地方是,前端必须写一些代码来保存这个token,然后在发送请求的地方要写一些代码把token携带在请求里。

优点

前端代码可以写的少一些,比如禁用UI元素的代码可以不写

能够解决在还未响应302之前,用户刷新浏览器导致的重复请求

适应有些场景下压根不能使用重定向

缺点

前、后端开发人员忘记写相关代码。这个真的解决不了。

无法控制通过脚本运行的,具有整套流程的恶意请求。这种请求在程序看来完全合法,但却属于恶意行为,针对这类恶意行为的防控属于另一个话题,本人不懂,所以在这里就不多讲了。

方法五:利用数据库的唯一约束

如果请求会insert数据,而这个数据正好存在业务主键,那么可以利用数据库的唯一约束来做进一步的防御。

方法六:请求幂等化

有些业务情形下,请求是幂等的,这就意味着可以不用为重复发生请求而烦恼了——至少在业务逻辑层面不用烦恼了。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/71141.html

相关文章

  • Web项目如何防止户端重复发送请求

    摘要:在项目中,有一些请求或操作会对数据产生影响比如新增删除更新,针对这类请求一般都需要做一些保护,以防止用户有意或无意的重复发起这样的请求导致的数据错乱。本文总结了一些防止客户端重复发送请求的方法。 在Web项目中,有一些请求或操作会对数据产生影响(比如新增、删除、更新),针对这类请求一般都需要做一些保护,以防止用户有意或无意的重复发起这样的请求导致的数据错乱。 本文总结了一些防止客户端重...

    fireflow 评论0 收藏0
  • 从零开始搭建论坛(一):Web服务器与Web框架

    摘要:服务器通过协议与客户端通信,因此也被称为服务器。本文标题为从零开始搭建论坛一服务器与框架本文链接为更多阅读自己动手开发网络服务器一自己动手开发网络服务器二自己动手开发网络服务器三服务器网关接口实现原理分析最佳实践指南应用浅谈框架编程简介 之前用 Django 做过一个小的站点,感觉Django太过笨重,于是就准备换一个比较轻量级的 Web 框架来玩玩。Web.py 作者已经挂掉,项目好...

    dantezhao 评论0 收藏0
  • javascript知识点

    摘要:握手过程中使用了的标志和。接收端收到后,回传一个带有标志的数据包以示传达确认信息。第四次挥手主动关闭方收到后,发送一个给被动关闭方,确认序号为收到序号,至此,完成四次挥手。其次,通过使和系统绑定来降低泄露后的危险。 一些开放性题目 1.自我介绍:除了基本个人信息以外,面试官更想听的是你与众不同的地方和你的优势。 2.项目介绍 3.如何看待前端开发? 4.平时是如何学习前端开发的? 5....

    zhangxiangliang 评论0 收藏0
  • 超实用百道Java面试题

    摘要:是的简称,运行环境,为的运行提供了所需的环境。分割字符串,返回分割后的字符串数组。当计算的值相同时,我们称之为冲突,的做法是用链表和红黑树存储相同的值的。迭代器取代了集合框架中的,迭代器允许调用者在迭代过程中移除元素。 Java基础1.JDK和JRE有什么区别? JDK 是java development kit的简称,java开发工具包,提供java的开发环境和运行环境。JRE 是j...

    MkkHou 评论0 收藏0
  • 【备战春招/秋招系列】美团面经总结基础篇 (附详解答案)

    摘要:不同于个人面经,这份面经具有普适性。我在前面的文章中也提到了应该怎么做自我介绍与项目介绍,详情可以查看这篇文章备战春招秋招系列初出茅庐的程序员该如何准备面试。是建立连接时使用的握手信号。它表示确认发来的数据已经接受无误。 showImg(https://segmentfault.com/img/remote/1460000016972448?w=921&h=532); 该文已加入开源文...

    Leck1e 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<