从 v0.22.0 开始,Axios 支持 AbortController 以 fetch API 的方式取消请求
bash
官方例子
const controller = new AbortController();
axios.get('/foo/bar', {
signal: controller.signal
}).then(function(response) {
//...
});
// cancel the request
controller.abort()
bash
request.js
import axios from 'axios'
import { ElNotification, ElMessageBox, ElMessage, ElLoading } from 'element-plus'
const errorCode = {
'401': '认证失败,无法访问系统资源',
'403': '当前操作没有权限',
'404': '访问资源不存在',
'default': '系统未知错误,请反馈给管理员'
}
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// 超时
timeout: 10000
})
// 声明缓存请求的集合
const pendingRequest = new Map();
// 基于请求的url和method 生成请求key
const generateRequestKey = (config) => {
const { method,url } = config;
return [ method,url ].join('&')
}
// 缓存正在penging的请求
const addPendingRequest = (config)=>{
const requestKey = generateRequestKey(config);
if(pendingRequest.has(requestKey)){
const controller = pendingRequest.get(requestKey);
controller.abort()
pendingRequest.delete(requestKey);
}
const controller = new AbortController();
config.signal = controller.signal;
pendingRequest.set(requestKey,controller)
}
// 删除请求集合
const removePendingRequest = (config)=>{
const requestKey = generateRequestKey(config);
if(pendingRequest.has(requestKey)){
pendingRequest.delete(requestKey);
}
}
// request拦截器
service.interceptors.request.use(config => {
// 是否需要设置 token
addPendingRequest(config)
return config
}, error => {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
removePendingRequest(res.config)
// 未设置状态码则默认成功状态
const code = res.data.code || 200;
// 获取错误信息
const msg = errorCode[code] || res.data.message || errorCode['default']
if (code == 401) {
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code == 500) {
ElMessage({ message: msg, type: 'error' })
return Promise.reject(new Error(msg))
} else if (code == 601) {
ElMessage({ message: msg, type: 'warning' })
return Promise.reject(new Error(msg))
} else if (code != 200) {
ElNotification.error({ title: msg })
return Promise.reject('error')
} else {
return Promise.resolve(res.data)
}
},
error => {
console.log('err' + error)
let { message } = error;
if (message == "Network Error") {
message = "后端接口连接异常";
} else if (message.includes("timeout")) {
message = "系统接口请求超时";
} else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
return Promise.reject(error)
}
)
export default service
bash
调用
<script setup>
import { getList } from '@/api/requestApi'
const getListFn = () => {
getList().then(res => {
console.log(res)
})
}
</script>
<template>
<div class="index">
index
<button @click="getListFn">getList</button>
</div>
</template>
<style lang="scss" scoped>
</style>
效果
只有最后一个 能正常请求