const pendingRequest = new Map(); // 请求对象
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
var qs = require('qs');
export function dataFromServer(apiUrl, type, param, data) {
const request = axios.create();
// 创建一个新的axios实例对象 这样做的目的就是 不会进入之前的请求拦截和响应 防止进入死循环
// 添加请求拦截器
request.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么
// 获取请求key
let requestKey = getReqKey(config);
if (pendingRequest.has(requestKey)) { // 是重复请求
//let cancel;
//config.cancelToken = new CancelToken(function executor(c) {
//cancel = c;
//})
//cancel();
//source.cancel('Operation canceled by the user.');
removeReqKey(requestKey);
} else {
// 设置cancelToken
config.cancelToken = new CancelToken(function executor(cancel) {
pendingRequest.set(requestKey, cancel); // 设置
})
}
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 添加响应拦截器
request.interceptors.response.use(
function (response) {
//let requestKey = getReqKey(response.config);
//removeKey(requestKey);
let requestKey = getReqKey(response.config);
removeReqKey(requestKey);
return response;
},
async function (error) {
//删除失败响应
if (error.response?.config) {
let requestKey = getReqKey(error.response.config);
removeKey(requestKey);
}
// 对响应错误做点什么
// 对响应数据做点什么
const status = error.response?.status;
if (status == 400) {
// 请求参数错误
}
return Promise.reject(error);
}
);
function removeReqKey(key) {
if (pendingRequest.has(key)) {
const cancelToken = pendingRequest.get(key);
cancelToken(key); // 取消之前发送的请求
pendingRequest.delete(key); // 请求对象中删除requestKey
}
}
function removeKey(key) {
if (pendingRequest.has(key)) {
pendingRequest.delete(key); // 请求对象中删除requestKey
}
}
function getReqKey(config) {
// 请求方式、请求地址、请求参数生成的字符串来作为是否重复请求的依据
const { method, url, params, data } = config; // 解构出来这些参数
// GET ---> params POST ---> data
const requestKey = [method, url, qs.stringify(params),
qs.stringify(data)].join('&');
console.log(config)
return requestKey;
}
/**
* 返回的Promise对象含有then、catch方法
*/
return new Promise(function (resolve, reject) {
request({
url: apiUrl,
method: type,
params: param,
data: data,
headers: {
'Content-Type': 'application/json',
},
cancelToken: source.token
}).then(function (response) {
resolve(response);
}).catch(function (error) {
let errStr;
if (error && error.response) {
if (parseInt(error.response.status, 10) === 401) {
//返回失败 做跳回登录页面操作
return;
}
errStr = error.response.data
}
reject(error);
})
})
}
Axios封装拦截器
于 2022-11-08 09:44:18 首次发布