接口如何处理重复请求(接口防刷)?

本文介绍五种处理接口重复请求的方法,包括前端按钮锁定、后端AOP切面处理、数据库唯一索引、业务参数去重及自定义starter限流。

本文主要来源于 处理重复请求的三种方式
服务端如何高效的处理重复请求
对其整理和总结,用于学习记录。

重复请求常用的处理方式就是幂等性处理,幂等性可以理解为:无论执行了多少次重复请求,数据只会处理一次,在数据库里也只会有一条数据。和数据库的唯一索引是一样的。

方式一:前端处理

优点:前端可在用户点击之后将按钮锁定,不可点击,直到后端返回数据才释放锁。前端处理是最为简单有效,且对用户比较友好的方式。可用提示语提醒用户等待。

缺点:无法应对直接刷后端接口的情况,如果用户直接调后端接口,无法处理(属于特殊情况)。

方式1:ajax防止重复提交

这里我用登录页面功能作为例子讲解,按下面的方法,用户在点击登录后,按钮会不可点击,直到后端返回结果,关键js代码如下:

function login(){
   
   
    //1.去用户名密码
	var user=$("#inputName").val();
	var pwd=$("#inputPassword").val();

	//2.让提交按钮失效,以实现防止按钮重复点击
	$("#loginBtn").attr('disabled', 'disabled');
  
	//3.给用户提供友好状态提示
	$("#loginBtn").text('登录中...');
  
	//4.异步提交
	$.ajax({
   
   
		type:"POST",
		url:"/verifylogin",
		dataType:"json",
		data:{
   
   
			"username":user,
			"password":pwd
		},
		success : function(data) {
   
   
			//登录成功跳转
		},
		error:function(){
   
   
			//5.失败后,登录按钮重新有效
			$("#loginBtn").removeAttr('disabled');
			alert("登录 发生错误");
		}
	});
}

方式2:vue按钮防止短时间内多次点击

定义了一个Vue指令,名为preventReClick
它的作用是防止用户在2秒内重复点击某个按钮。

当用户点击按钮时,按钮的disabled属性会被设置为true,并且按钮的背景颜色会被设置为#ccc,边框会被设置为none,鼠标样式也会被设置为not-allowed。

2秒后,按钮会被重置,disabled属性会被设置为false,背景颜色被设置为#002FA8,边框被设置为1px solid #002FA8,鼠标样式也会被设置为pointer。

import Vue from 'vue'
const preventReClick = Vue.directive('preventReClick',{
   
   
	inserted: function(el, binding, vNode, oldVnode){
   
   
		el.addEventListener('click', () => {
   
   
			if(!el.disabled){
   
   
			    el.disabled = true
			    el.style.backgroundColor = '#ccc'
			    el.style.border = 'none'
                el.style.cursor = 'not-allowed'
       			setTimeout(() => {
   
   
          			el.disabled = false
          			 el.style.backgroundColor = '#002FA8'	
          			 el.style.border = '1px solid #002FA8'
                     el.style.cursor = 'pointer'
        		}, 2000)
			}
		})
	}
})

export default {
   
   
	preventReClick 
}

使用方法也很简单

在main.js里引用

//防频繁点击
import  preventReClick  from '@/utils/directive'
Vue.use( preventReClick )

直接调用即可

 <el-button v-preventReClick>确认</el-button>

方式二:后端AOP切面处理或者拦截器处理

后端处理逻辑是需要使用额外的存储数据,记录用户访问接口次数。在重复提交时拦截请求,对于重复的请求直接返回就行,不做任何处理。
方式:自定义注解+AOP

这里我用springboot2+redis+maven 构造示例,请求的思路是将用户访问记录缓存,5s内,请求的记录在redis中有记录时直接抛出异常。

自定义注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({
   
   ElementType.METHOD, ElementType.TYP
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值