如何防止重复提交请求?

 

下面说的防重操作,如支付功能订单提交业务、表单提交、手机验证码功能。

 

订单提交为什么需要防重呢?想像一下你在商城购物,你选中商品点击提交订单,如果这时网络延迟没有返回成功提示,你又多点了几次。每点一次都会发送提交订单请求,若是没做防重处理,会出现生成多个订单情况。同样商城系统商品添加功能,用户不小心点了多次表单提交,若防重处理没做,将会添加多个商品。

 

如何实现防止重复提次请求操作,确保Web应用或API的健壮性和用户体验呢?我们分别从前后端操作上来说一说:

 

前端防重处理

1. 禁用按钮:在用户点击提交按钮后立即禁用它,直到服务器响应完成。

禁用按钮在注册获取手机验证码场景经常用到。点击获取验证码按钮后,按钮立即变为灰色显示禁用状态,读秒结束后恢复正常。

2. 显示加载指示:提交过程中显示加载动画或提示,防止用户再次点击。

在登录界面,用户点击登录按钮,请求登录接口后,出现加载动画,防止用户重复点击。

3. 限制提交频率:使用防抖(debounce)和节流(throttle)技术来限制事件触发的频率。

在用户点击提交按钮后,使用防抖或节流的技术延迟发送请求,确保只发送一次请求。防抖和节流是一种常见的前端性能优化技术,可以控制函数的执行频率。

在搜索框输入内容时,可能需要在用户停止输入一段时间后才发送请求,以减少请求的次数。在用户调整浏览器窗口大小时,可能需要在用户停止调整后计算布局或重新渲染页面。在用户连续按键时,例如在输入密码时,可以限制按键事件的处理频率。

 

后端防重处理

1. 唯一ID机制:生成一个唯一的ID,并在客户端提交时一并发送,服务器验证ID后进行处理。

 

以订单业务为例,实现的逻辑流程如下:

  1. 当用户进入订单提交界面的时候,调用后端获取请求唯一ID,并将唯一ID值埋点在页面里面;
  2. 当用户点击提交按钮时,后端检查这个唯一ID是否用过,如果没有用过,继续后续逻辑;如果用过,就提示重复提交
  3. 最关键的一步操作,就是把这个唯一ID 存入业务表中,同时设置这个字段为唯一索引类型,从数据库层面做防止重复提交

 

 

 

防止重复提交的大体思路如上,实践代码如下!

1. 给数据库表增加唯一键约束

2 编写获取请求唯一ID的接口

3 业务提交的时候,检查唯一ID

对于下单流量不算高的系统,可以采用这种请求唯一ID+数据表增加唯一索引约束的方式,来防止接口重复提交!虽然简单粗暴,但是十分有效!

2. 分布式锁+全局唯一的ID=Redis+Token: 分布式锁实现解决JVM锁实现单机锁局限问题

具体流程步骤:

  1. 客户端先请求服务端,会拿到一个能代表这次请求业务的唯一字段
     
  2. 将该字段以 SETNX 的方式存入 redis 中,并根据业务设置相应的超时时间
        
  3.  如果设置成功,证明这是第一次请求,则执行后续的业务逻辑
      
  4. 如果设置失败,则代表已经执行过当前请求,直接返回

Token实现:生成唯一ID

3. 幂等性设计:

幂等设计,即多次执行同一操作的结果与执行一次相同。这通常通过在接口设计时考虑实现。

总结

防止重复提交是确保Web应用或API的健壮性和用户体验的重要措施。为了防止绕过前端限制通过工具重复请求接口,在防重处理时需要前后端配合。

除了我们介绍的几种方式外还有其它方式和封装好的工具,如:react中可以用swr、ahook,vue中用VueRequest。每种方法都有其适用场景,通常需要根据具体的业务需求和系统架构来选择最合适的策略。在设计系统时,应该综合考虑多种方法,以实现最佳的效果。

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/18545.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot入门,idea搭建一个简单SpringBoot项目

初学者搭建一个简单的SpingBoot项目 在IntelliJ IDEA中直接创建一个新的Spring Boot项目非常直观便捷,下面是详细的步骤指南: 第1步:打开IntelliJ IDEA并创建新项目 打开IntelliJ IDEA。选择菜单栏的“File” > “New” > “Project”…

Github 2024-05-29 C开源项目日报 Top10

根据Github Trendings的统计,今日(2024-05-29统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目10C++项目3PHP项目1PHP:流行的Web开发脚本语言 创建周期:4710 天开发语言:C, PHP协议类型:OtherStar数量:37340 个Fork数量:7657 次…

MySQL 按年月日统计,创建视图

按日统计,前十天 SELECTdays.day dateField,COALESCE(COUNT(archive_no), 0) AS total_quantityFROM(SELECTDATE_FORMAT(DATE_SUB(now(), INTERVAL a.a DAY), %Y-%m-%d) AS dayFROM(SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION…

003 仿muduo实现高性能服务器组件_前置知识

​🌈个人主页:Fan_558 🔥 系列专栏:仿muduo 🌹关注我💪🏻带你学更多知识 文章目录 前言时间轮timewheel设计正则表达式介绍(了解知道怎么使用)通用型any容器的实现 小结 …

让 AI 回答更精准 来学学这些Prompt入门小技巧

🎥前言 最近一直在研究各种 AI 提问相关的方法,一顿输入后,get到了好多有趣又好玩的提问小技巧。今天就来和小伙伴们安利下,平常在向AI提问时,最最基础,且最最实用的6种提示词方法。 那废话不多说&#x…

java全套idea jdk maven历史版本下载

idea多版本 Other Versions - IntelliJ IDEA jdk,需要登陆 https://www.oracle.com/java/technologies/downloads/ maven多版本 Maven – Maven Releases History

如何使用git上传linux下的项目!---附带每一步截图

在实际项目中,我们需要把自己的模块递给GitHub,需要别人的模块的时候拉下来,那么我们怎么把自己的项目递给GitHub呢?下面做一个总结: 登录GitHub 创建一个仓库 填写相关信息 项目名称是必填的,项目描述可以…

语音控制系统的安全挑战与防御策略(中)

2.3 核心层 在VCS中,核心层负责解码预处理层处理后的音频特征向量。这种解码传统上是通过声学模型实现的,它将特征向量转换为音素,并使用语言模型预测词序列概率,以输出最可能的句子。目前Wav2Letter(基于CNN&#xf…

「架构」模型驱动架构设计方法及其运用

本文通过一个实际的软件项目案例,深入探讨了模型驱动架构(MDA)在软件开发全过程中的应用。MDA是一种以模型为中心的设计方法,它通过分离计算、数据和业务逻辑,提高了软件的可维护性、可扩展性和可移植性。文章将从需求分析、架构设计、实现与测试三个阶段出发,分析MDA的应…

FaceChain-FACT:开源10秒写真生成,复用海量LoRa风格,基模友好型写真应用

github开源地址:https://github.com/modelscope/facechain/tree/main/facechain_adapter 魔搭创空间应用体验:魔搭社区 一、效果演示 FaceChain FACT的代码和模型目前已经在github和modelscope创空间上同步开源。FaceChain FACT具有简单的交互式界面设…

AI图书推荐:基于ChatGPT API和Python开发应用程序的详细指南

ChatGPT已经以其革命性的能力引起了人们的关注,利用其API可能会成为你的游戏规则改变者。这不仅仅是关于编码;它是关于为您的创作添加一层智能,将它们提升到之前无法想象的水平。《基于ChatGPT API和Python开发应用程序的详细指南》&#xff…

[图解]企业应用架构模式2024新译本讲解03-事务脚本+表数据入口

1 00:00:00,570 --> 00:00:06,290 这里先创建一个service的对象 2 00:00:07,000 --> 00:00:12,470 然后调用对象的方法、操作 3 00:00:12,480 --> 00:00:13,750 就是事务脚本 4 00:00:14,700 --> 00:00:15,900 然后参数是1 5 00:00:16,660 --> 00:00:19,490…

《公正》孙溟㠭艺术

孙溟㠭艺术《公正》 孙溟㠭艺术《公正》

利用NewGIS平台将FME模板发布为接口

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 一、模板编写 二、发布模板 三、接口获取 四、移动端调用 ​​​​​ 前言 在实际的应用生产过程中,尤其是移动端GIS软件的开发,针对一些闭…

【社区投稿】给 NdArray 装上 CUDA 的轮子

Ndarry是Rust编程语言中的一个高性能多维、多类型数组库。它提供了类似 numpy 的多种多维数组的算子。与 Python 相比 Rust 生态缺乏类似 CuPy, Jax 这样利用CUDA 进行加速的开源项目。虽然 Hugging Face 开源的 candle 可以使用 CUDA backend 但是 candle 项瞄准的是大模型的相…

12.2 通道-阻塞与流程控制、通道型函数、退出通道

阻塞与流程控制 通常在并发程序中要尽力避免阻塞式操作,但有时又需要让代码暂时处于阻塞状态,以等待某种条件、信号或数据,然后再继续运行。 对于无缓冲通道,试图从无人写入的通道中读取,或者向无人读取的通道中写入…

Redis教程(二十一):Redis怎么保证缓存一致性

传送门:Redis教程汇总篇,让你从入门到精通 Redis 的缓存一致性 Redis 的缓存一致性是指在使用 Redis 作为缓存层时,保证缓存中的数据与数据库中的数据保持一致的状态。在分布式系统中,数据一致性是一个重要的问题,因为可能存在多个客户端同时读写同一数据,或者数据在不同…

【量算分析工具-贴地面积】GeoServer改造Springboot番外系列十

【量算分析工具-概述】GeoServer改造Springboot番外系列三-CSDN博客 【量算分析工具-水平距离】GeoServer改造Springboot番外系列四-CSDN博客 【量算分析工具-水平面积】GeoServer改造Springboot番外系列五-CSDN博客 【量算分析工具-方位角】GeoServer改造Springboot番外系列…

SQL学习小记(三)

SQL学习小记(三) 功能实现思路代码部分名词解释 代码打包为可执行文件 功能说明:使用python代码,将数据库database1中的表格table1同步到数据库database2中 功能实现 思路 #mermaid-svg-R1pWrEWA799M299a {font-family:"tre…

go语言方法之基于指针对象的方法

当调用一个函数时,会对其每一个参数值进行拷贝,如果一个函数需要更新一个变量,或者 函数的其中一个参数实在太大我们希望能够避免进行这种默认的拷贝,这种情况下我们就需 要用到指针了。对应到我们这里用来更新接收器的对象的方法…