前言
在实际项目中,我们可能需要对请求进行“防抖”处理。这里主要是为了阻止用户在某些情况下短时间内重复点击某个按钮,导致前端向后端重复发送多次请求。这里我列举两种比较常见的实际情况:
- PC 端 - 用户双击搜索按钮,可能会触发两次搜索请求
- 移动端 - 因移动端没有点击延迟,所以极易造成误操作或多操作,造成请求重发
核心——CancelToken
在 Axios 中取消请求最核心的方法是 CanelToken
注意设置是全局请求拦截,所以当有些请求让它重复请求的话 设置白名单
1 2 3 4 5
| let whiteListUrls = [ "/sysUser/checkRepeat", ... ];
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| let reqList: any[] = [];
const stopRepeatRequest = function ( reqList: any, url: string, cancel: any, errorMessage?: string ) { const errorMsg = errorMessage || ""; for (let i = 0; i < reqList.length; i++) { if (reqList[i] === url && !whiteListUrls.includes(url)) { cancel(errorMsg); return; } } reqList.push(url); };
const allowRequest = function (reqList: any, url: string) { for (let i = 0; i < reqList.length; i++) { if (reqList[i] === url && !whiteListUrls.includes(url)) { reqList.splice(i, 1); break; } } };
|
在 axios 请求拦截器中设置如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| service.interceptors.request.use( (config) => { if (store.getters.token) { config.headers["Authorization"] = getToken(); } let cancel; config.cancelToken = new axios.CancelToken(function(c) { cancel = c; }); stopRepeatRequest(reqList, config.url as string, cancel); return config; }, (error) => { Promise.reject(error); } );
|
在响应拦截器设置拦截的间隔
1 2 3 4 5 6 7
| service.interceptors.response.use( (response) => { let time = setTimeout(() => { allowRequest(reqList, response.config.url as string); clearTimeout(time); }, 200); })
|