Vue实现禁止反复发送请求
2022-10-09 本文已影响0人
空格x
- 其实实现上一个请求结束前禁止下次请求的方法很多,最常见的其实就是防抖等等,但如果对所有接口都进行这个操作就很繁琐,就算写一个公共的方法也是即此。
- 既然上面的方法繁琐,那不如从根源解决问题,已知所有的接口都会通过请求拦截器/请求响应器,那么可以从此处做手脚,一次性解决所有问题。
1.最基础的请求基础代码
import axios from 'axios'
import { getItem, removeItem } from '@/utils/token'
import { Message } from 'element-ui'
import router from '@/router'
const request = axios.create({
baseURL: "/api",
})
// 请求拦截器
request.interceptors.request.use(function (config) {
config.headers.Authorization = `Bearer ${getItem("token")}`
return config;
})
// 响应拦截器
request.interceptors.response.use(function (config) {
const { status, message } = config.data
if (status == '500') {
Message.error('登录已过期,请重新登录')
removeItem('token')
router.push('/login')
} else if (status !== '200' && status !== '500') {
Message.error(message)
}
return config
}, error => {
console.log(error);
return Message.error(error)
})
export default request
2. 获取这次请求的请求信息,并做重复拦截
let requestList = []
// 请求拦截器
// 同时记录请求地址与请求方式防止拦截错误
request.interceptors.request.use(function (config) {
if (requestList.findIndex(x => x.config === `${config.url}&${config.method}`) === -1) {
requestList .push({ config: `${config.url}&${config.method}` })
} else {
return
}
config.headers.Authorization = `Bearer ${getItem("token")}`
return config;
})
3. 请求结束后清除此接口信息
// 响应拦截器
request.interceptors.response.use(function (config) {
requestList = requestList.filter((x,index)=>x.config !== `${config.config.url}&${config.config.method}`)
const { status, message } = config.data
if (status == '500') {
Message.error('登录已过期,请重新登录')
removeItem('token')
router.push('/login')
} else if (status !== '200' && status !== '500') {
Message.error(message)
}
return config
}, error => {
console.log(error);
return Message.error(error)
})
- 但这样会有个问题,当请求拦截器不
return config
时会报一个错误出来
TypeError: Cannot read properties of undefined (reading 'cancelToken')
- 具体解决的话,建议是单独做个判断,当报错信息为上面时,不进行错误提示
4. 完整代码
import axios from 'axios'
import { getItem, removeItem } from '@/utils/token'
import { Message } from 'element-ui'
import router from '@/router'
const request = axios.create({
baseURL: "/api",
let requestList = []
// 请求拦截器
// 同时记录请求地址与请求方式防止拦截错误
request.interceptors.request.use(function (config) {
if (requestList.findIndex(x => x.config === `${config.url}&${config.method}`) === -1) {
requestList .push({ config: `${config.url}&${config.method}` })
} else {
return
}
config.headers.Authorization = `Bearer ${getItem("token")}`
return config;
})
// 响应拦截器
request.interceptors.response.use(function (config) {
requestList = requestList.filter((x,index)=>x.config !== `${config.config.url}&${config.config.method}`)
const { status, message } = config.data
if (status == '500') {
Message.error('登录已过期,请重新登录')
removeItem('token')
router.push('/login')
} else if (status !== '200' && status !== '500') {
Message.error(message)
}
return config
}, error => {
console.log(error);
return Message.error(error)
})
export default request