我们在开发时 经常会遇到类似场景
- 提交表单时,连续点击提交表单,导致后台重复处理
- 写一个连续点击脚本,不停发送请求,并发量导致服务器瘫痪
今天,我们解决类似问题:
一、重复请求
处理流程:
代码:
request.js
引入请求以及部分组件,并且定义一个变量用来存储请求url
import axios from 'axios'
import { Message, Notification } from 'element-ui'
let requestList = new Set() // 存储请求url
请求发出前,利用拦截器判断当前是否存在请求,如果存在利用cancelToken取消,反之添加到数组中
// 请求前拦截器
axios.interceptors.request.use(config => {
// 利用cancelToken 取消当次请求
config.cancelToken = new axios.CancelToken(e => {
// 在这里阻止重复请求,上个请求未完成时,相同的请求不会再次执行
requestList.has(config.url) ? e(`${location.host}${config.url}---重复请求被中断`) : requestList.add(config.url)
})
return config
}, error => {
Message.error('未知错误')
return Promise.reject(error)
})
利用响应拦截器,在这里处理已发送或者被动取消的请求
已发送请求无论成功与否,务必在数组中清除掉
这里根据需求处理:
- 成功的业务逻辑
- 取消的业务逻辑
- 失败的业务逻辑
// 响应拦截器
axios.interceptors.response.use(response => {
// 相同请求不得在600毫秒内重复发送,反之继续执行
setTimeout(() => {
requestList.delete(response.config.url)
}, 600)
// 请求成功业务逻辑
if (response.data.code == '200') {
return response.data
} else {
switch (response.data.code) {
case 201:
Message.warning('您提交的信息异常')
break
case 203:
Notification({
title: '提示',
message: response.data.msg,
type: 'error',
showClose: true,
})
router.replace({path: '/login'})
break;
default:
Message.error(response.data.msg)
}
}
}, error => {
// 这里判断异常情况,如果axios.isCancel 为 true时,说明请求被取消
if (axios.isCancel(error)) {
// 请求取消
console.warn(error)
console.table([error.message.split('---')[0]], 'cancel')
} else {
// 请求失败
if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
Message.warning('请求超时')
} else if (error.message == 'Network Error') {
Message.error('网络连接异常,请重试')
} else {
Message.error('未知错误', error.message)
}
// 请求如果失败了,务必从列表里面删掉,否则请求拦截器会取消请求
requestList.delete(error.config.url)
}
return Promise.reject(error)
})
总结:
- 请求拦截器
利用数组存储每次发出请求url,请求拦截器判断数组是否存在此次请求url,如果存在,调用cancelToken取消请求并且清除url,反之url添加到数组中 - 响应拦截器
本次请求不论成功与否,清除本次url记录,否则会拦截取消请求
- 可以使用同一个 cancel token 取消多个请求
注意:
效果:
至此,我们就成功拦截了重复请求
链接:
版权声明:本文为Vue2018原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。