// 思路:定义存放请求时token过期的接口数组
// 判断token过期的接口是否是刷新token的接口,否的话就请求刷新token的接口
// 刷新token接口请求成功就重新请求需要重新请求的接口
import axios from 'axios';
// 创建 axios 实例
const instance = axios.create({
timeout: 20000, // 默认请求超时时间
baseURL: ''
});
// 刷新token
let isRefreshing = false; // 标记是否正在刷新 token 或 判断token是否超时
let requests = []; // 存储需要重新发送的请求
const refreshToken = () => {
return instance({
url: 'refreshTokenUrl', // 刷新token的url
method: 'post',
data: {
token: localStorage.getItem('token')
}
});
};
// request拦截器
instance.interceptors.request.use(
config => {
return config;
},
error => {
Promise.reject(error);
}
);
//响应拦截器
instance.interceptors.response.use(
res => {
return res.data;
},
error => {
// 判断请求的接口是超时 并且 不包含刷新token的接口
if (error.response?.status === 401 && !error.config.url.includes('refreshTokenUrl')) {
// 刷新token
const { config } = error;
if (!isRefreshing) {
isRefreshing = true;
return refreshToken()
.then(res => {
if (res.token) {
// 存储token
localStorage.setItem('token', res.token);
//*********************** */
// 这里放还需要刷新的接口
//*********************** */
// 获取token刷新后将数组的方法重新执行
requests.forEach(cb => cb(res.access_token));
requests = []; // 重新请求完清空
return instance(config);
} else {
// 清除缓存
localStorage.clear();
}
})
.finally(() => {
isRefreshing = false;
});
} else {
// 将处于请求refreshToken时间内发起请求存在数组中,等待refreshToken响应后发起请求
return new Promise(resolve => {
// 用函数形式将 resolve 存入,等待刷新后再执行
requests.push(token => {
config.headers.token = token;
resolve(instance(config));
});
});
}
}
return Promise.resolve(error.response?.data);
}
);
// 整体的请求类型归类,对统一的输入做整理
export default {
get: (url = '', params = {}, option = {}) => {
return instance({
url,
method: 'GET',
params,
...option,
withCredentials: false
});
},
post: (url = '', params = {}, option = {}) => {
return instance({
url,
method: 'POST',
data: params,
...option,
withCredentials: false
});
},
put: (url = '', params = {}, option = {}) => {
return instance({
url,
method: 'PUT',
data: params,
...option,
withCredentials: false
});
},
delete: (url = '', params = {}, option = {}) => {
return instance({
url,
method: 'DELETE',
data: params,
...option,
withCredentials: false
});
},
fetch: (option = {}) => {
return instance(option);
}
};
token过期 刷新token
于 2023-03-01 23:05:34 首次发布