点击上方「蓝字」关注我们 0x01: 背景 同一条数据被用户点击了多次,导致数据冗余,需要防止弱网络等环境下的重复点击 0x02: 目标 通过在指定的接口处添加注解,实现根据指定的接口参数来防重复点击...0x03: 说明 这里的重复点击是指在指定的时间段内多次点击按钮 0x04: 技术方案 springboot + redis锁 + 注解 使用 feign client 进行请求测试 0x05...:实战演练 1、根据接口收到 PathVariable 参数判断唯一 /** * 根据请求参数里的 PathVariable 里获取的变量进行接口级别防重复点击 * *...} 2、根据接口收到的 RequestBody 中指定变量名的值判断唯一 /** * 根据请求参数里的 RequestBody 里获取指定名称的变量param5的值进行接口级别防重复点击...java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * TestControllerTest * @description 防重复点击测试类
什么是重复提交。(张三买裤子这个场景) 张三下单买一条黑色的型号是AA的裤子,点击下单的时候,卡了一下,半天不出来,暴躁张三连续点击了10下,于是后台识别为:张三下单买一条黑色的型号是AA的裤子。...张三实际只要1条裤子,这就是重复提交。 如何识别重复提交 可以获取用户账号、请求资源、请求参数。 解决方案 防重复提交有两种环节实现。 在请求入口限制 后端服务入口限制。
利用Spring MVC的过滤器及token传递验证来实现表单防重复提交。...create() default false; boolean remove() default false; } 在跳转页面的方法上加上:@Token(create = true)\ 在提交的...remove) { if (isRepeatSubmit(request)) { logger.warn("表单不能重复提交...{session.getAttribute('token')}"/> 在form表单里面添加token域,提交表单时需要传过去。
根据了解,我们可以使用curator的读写锁来做一个分布式防重复提交的策略。为什么采用curator来做这个事情的原因是curator提供的读写锁能够跨线程和jvm进行加锁。...如果不加锁,那么因为网络抖动或者线程切换,谁都不知道防重复提交的token标志是否被其他请求修改。因此这块必然要采用加锁的方式。...对于放重复提交的一般规则来说,我无非就是将session提取出来,而session则是和用户绑定的,因此这块我们将userId作为放重复提交的判断标志,将token表示该用户下次提交的表单的有效token...} 测试代码 @RestController @RequestMapping(value = "/zklock") public class TestLock { /** * 防重复提交...return ResponseResult.error(newToken); } } } 在浏览器中发送请求: 一些反思:通过逻辑分析,这里做的防重复提交的工具适合做单个有序接口
但前端的限制仅能解决少部分问题,且不够彻底,后端自有的防重复处理措施必不可少,义不容辞。 在接口实现中,我们常要求接口要满足幂等性,来保证多次重复请求时只有一次有效。...比如第三方支付前台回调和后台回调,第三方支付批量回调,慢性能业务逻辑(如用户提交退款申请,商家同意退货/退款等)或慢网络环境时,是重复处理的高发场景。...### 尝试 这里针对“用户提交退款申请”的例子,说明一下尝试过的防重复处理方法的效果。...后端防重复处理的方式,我们先后尝试了三种: #### (1)基于DB中退款订单状态的验证 这种方式简单直观,从DB查询出来的退款详情(包括状态)往往还可以用在后续逻辑中,没有花额外的工作专门应对重复请求的问题...但对于防重复处理效果并不好:在前端添加防重复提交前,每周平均在25笔;前端优化后,每周降到7笔。这个数量占总退款申请数的3%%,一个仍然无法接受的比例。
防抖(Debounce)是一种防止重复提交的策略,它通过延迟一定时间来合并连续的操作,以确保只执行一次。...// 清除会话中的 token unset($_SESSION['submit_token']); } Token防抖(利用随机生成的 token 来防止重复提交) $token = md5(...== $lastSubmitIP) { // 处理表单提交 $_SESSION['last_submit_ip'] = $userIP; } Cookie防抖 (利用Cookie来防止在一段时间内的重复提交...); // 60秒内不允许重复提交 } 延时防抖(在最后一次操作后的一段时间内,只执行一次提交操作) if (!...cache_get($cacheKey)) { // 处理表单提交 cache_set($cacheKey, 'submitted', 60); // 60秒内不允许重复提交 } 验证码防抖(要求用户输入特定的验证码来提交表单
前言啥是防抖思路解析分布式部署下如何做接口防抖?具体实现请求锁唯一key生成重复提交判断前言作为一名老码农,在开发后端Java业务系统,包括各种管理后台和小程序等。...啥是防抖 所谓防抖,一是防用户手抖,二是防网络抖动。在Web系统中,表单提交是一个非常常见的功能,如果不加控制,容易因为用户的误操作或网络延迟导致同一请求被发送多次,进而生成重复的数据记录。...如何确定接口是重复的?防抖也即防重复提交,那么如何确定两次接口就是重复的呢?...首先,我们需要给这两次接口的调用加一个时间间隔,大于这个时间间隔的一定不是重复提交;其次,两次请求提交的参数比对,不一定要全部参数,选择标识性强的参数即可;最后,如果想做的更好一点,还可以加一个请求地址的对比...第一次提交,"添加用户成功"短时间内重复提交,"BIZ-0001:您的操作太快了,请稍后重试"过几秒后再次提交,"添加用户成功"从测试的结果上看,防抖是做到了,但是随着缓存消失、锁失效,还是可以发起同样的请求
前几天,说要用curator的读写锁写一个分布式防重复提交的工具包。然后今天作者就探索一下,在上次文章的末尾,作者说当时的这种方式解决不了大量表单使用相同的防重复提交token上送。...其他都可能被视为重复的表单。但是作者后边想了想感觉这种情况还是比较少。很多时候表单都是单个提交的。所以我们先不考虑那种情况,因为如果考虑那种情况会比较复杂。...交由spring管理 DoubleSubmitAdvice 是对请求防重复提交token的生成处理。...reSubmitLock.check(userId, token)) { logger.warn(MessageFormat.format("重复提交的表单...status) { System.out.println("不能重复提交表单"); } return status; } /**
前言 form 表单提交的时候,当快速点击提交按钮的时候,会触发多个请求过去,会导致重复添加。...前端页面 前端form表单页面,2个输入框,一个提交按钮 这里用ajax提交请求 /** 定义表单提交事件 */ function project_save...(); }) 遇到问题,当快速点提交按钮多次,会触发多个请求 beforeSend 禁用添加按钮 解决办法,在点提交按钮,发请求之前,可以调用beforeSend 方法,添加一个disabled...:"+e); } }); } 这样就能解决快速点击,导致前端页面重复提交的问题 complete 完成请求 一般在 beforeSend 发请求之前禁用提交按钮
RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface RepeatSubmit { /** * 重复提交间隔时间...*/ int time() default 3000; String msg() default "请勿重复提交"; } 创建访问的资源路径 @RestController
应用情景 经典使用情景:js的一些事件,比如:onresize、scroll、mousemove、mousehover等; 还比如:手抖、手误、服务器没有响应之前的重复点击; 这些都是没有意义的,重复的无效的操作...节流函数 所谓的节流函数顾名思义,就是某个时刻限制函数的重复调用。 同样节流函数也是为了解决函数重复提交的问题,而防止重复提交的方法,不止节流函数一种实现。...方法汇总 本文整理了我在工作实践当中,觉的防止js重复提交,比较好用的方法,在这里和大家分享一下。...一、setTimeout + clearTimeout(节流函数) 本文提供两种实现方式:普通节流函数和闭包节流函数 二、设定flag/js加锁 三、通过disable 四、添加浮层比如loading...业务代码 lock = false; }); }); 总结 前两种方式实现起来比较方便,而后两种实现起来相对比较繁琐,如果是为了防止事件的多次触发,建议使用闭包,如果是表单提交
提交form数据,假如提交的按钮是图片按钮而不是submit按钮,可以按下面方法防止按钮被多次提交: 1. -----------------------------------------------...script language="javascript"> var flag=false; dosubmit() { if (flag==true) { alert("傻比你已提交过了
表单提交时需要校验数据是否已存在,如果已存在需要防止重复提交,做法比较简单,不再赘述。...} } 2.View @model AspNetMvcModelValidate.Models.Employee <script src="~/Scripts/jquery-1.10.2.min.<em>js</em>
GET:用于获取资源,不应有副作用,所以是幂等的; POST:用于创建资源,重复提交POST请求可能产生两个不同的资源,有副作用不满足幂等性; PUT:用于更新操作,重复提交PUT请求只会对其URL中指定的资源有副作用...支付前系统本地相关业务处理 ; 请求第三方支付服务执行扣款; 第三方支付返回处理结果; 本地服务基于支付结果响应客户端; 该业务流程中要处理相当复杂的问题,比如事务,分布式事务,接口延迟超时,客户端重复提交等等...BIGINT (20) NOT NULL AUTO_INCREMENT COMMENT '订单id', `token_id` VARCHAR (50) DEFAULT NULL COMMENT '防重复提交...,订单是不能重复提交的,下面会演示如何控制,这里业务是执行后推到完成,也可能业务向前清理,把整个流程置为失败,这里涉及关键状态判断,要选取一个状态作为成功或失败的标识,判断后续操作流程。...三、接口重复提交 1、表单重复提交 在实际情况中,接口如果处理时间过长,用户可能会点击多次提交按钮,导致数据重复。
1.HTTP是如何提交表单的 标签的属性enctype设置以何种编码方式提交表单数据。...2.文件标签 标签用来提交文件。要注意的是,这个标签的value值并不是所选择的文件内容,而是这个文件的完整路径名。...正如前面所说的,表单在提交表单时,如果采用默认编码方式,文件的内容是不会被提交的。要提交文件内容要采用multipart/form-data编码方式,这需要在服务器端从提交的二进制流中读取文件内容。...Content-Disposition: form-data; name=”buttom” 上传 ——WebKitFormBoundaryQqpAxgR2Pgik6uyY– 可以看到提交的表单数据是混合了所有请求参数的数据
return false; }else{ $(this).attr("ctime",nowTime);//设置节点属性的值 alert('提交成功
//防止重复提交 var pendingRequests = {}; jQuery.ajaxPrefilter(function( options, originalOptions, ...pendingRequests[key]) { pendingRequests[key] = jqXHR; }else{ //jqXHR.abort(); //放弃后触发的提交... setTimeout(function(){console.log("放弃先触发的提交");},1); pendingRequests[key].abort...(); // 放弃先触发的提交 } var success = options.success; options.success = function(jqXHR
解决方案 在Web系统的交互设计中,表单提交是一个核心功能,但若不加以适当控制,用户误操作或网络的不稳定性都可能导致同一请求被重复发送,从而产生冗余数据。...为了应对这一挑战,我们可以从两个层面进行优化: 前端防抖:通过在用户界面上实现按钮的加载状态(loading state),可以有效防止用户因手抖而重复点击,从而避免前端生成多个请求。...因此,后端需要引入防抖逻辑,通过识别请求的唯一性(例如使用请求ID或时间戳),确保即便在网络不稳定的情况下,同一请求也不会被重复处理。 防抖策略是确保Web系统稳定性和数据一致性的关键。...防抖可以减少因快速输入导致的频繁请求。 表单输入:尤其是那些包含多个字段或需要进行复杂验证的表单,防抖可以避免用户因误操作而重复提交。...验证分布式锁 正确提交 后端异常提交 后端未响应之前提交 相同时间段内重复,锁释放剩余时间
防止表单重复提交: var flag = false; function jqButtonBC_onClickClient_insert(rc) { if (flag==false) { flag
领取专属 10元无门槛券
手把手带您无忧上云