数据可视化大屏项目开发中,项目的token有效期很短,这时候我们就需要使用刷新令牌进行token刷新,当接口code为401的时候,我们需要记录这些报401的接口,然后进行token刷新,刷新完成后,重新请求之前报401的接口以刷新数据。如果token刷新失败的话就直接跳转到登录页。
请求方法封装
import axios from 'axios'
// import {Message} from 'element-ui'
import {devIp} from '@/api/ipConfig'
import router from '@/router'
import {Message} from "element-ui";
import {refreshToken} from "@/api/api/LargeScreenData"; // 确保正确引入了router
// 刷新token的一个开关,防止重复请求
let isRefreshing = true;
let requestList = []
const service = axios.create({
baseURL: devIp + '', // 测试IP
timeout: 100000, // request timeout
})
// request interceptor
service.interceptors.request.use(config => {
config.headers['tenant-id'] = 1
let token = localStorage.getItem('accessToken')
// 后续接口请求头都需要加上 Authorization, Authorization='Bearer ' + accessToken
config.headers['Content-Type'] = 'application/json';
if (token) {
config.headers['Authorization'] = 'Bearer ' + token // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
}
return config
}, error => {
Promise.reject(error)
})
// 假设这个变量在合适的地方被定义
let isMessageShowing = false;
// respone interceptor
service.interceptors.response.use(
// response => response,
async response => {
const res = response.data
if (res.code == 401) {
const originalConfig = response.config;
isRefreshing = true;
try {
let refreshTokenData = localStorage.getItem('refreshToken');
// 调用 refreshToken 函数,传递当前的 refreshToken
const refreshTokenRes = await refreshToken({refreshToken: refreshTokenData});
// 从接口返回的数据中解构出新的 accessToken 和 refreshToken
const {accessToken, refreshToken: newRefreshToken} = refreshTokenRes.data;
// 更新本地存储中的 accessToken 和 refreshToken
localStorage.setItem('accessToken', accessToken);
localStorage.setItem('refreshToken', newRefreshToken);
isRefreshing = false;
// 重新发起队列中的请求
requestList.forEach(cb => cb(accessToken));
requestList = [];
return service(originalConfig); // 用新的令牌重新发起失败的请求
} catch (refreshError) {
// 刷新令牌失败的处理逻辑...
// console.error('无法刷新令牌,需要重新登录', refreshError);
Message.error({
message: '登录状态已过期,请重新登录',
onClose: () => {
isMessageShowing = false; // 当消息关闭时,重置标志
}
});
localStorage.removeItem('accessToken');
router.push('/login');
// 清理登录状态,重定向到登录页...
return Promise.reject(refreshError);
} finally {
isRefreshing = false;
}
} else if (res.code == 500) {
if (!isMessageShowing) {
isMessageShowing = true;
Message.error({
message: res.msg || '发生错误,请稍后再试',
onClose: () => {
isMessageShowing = false; // 当消息关闭时,重置标志
}
});
}
}
return res;
},
async error => {
// 其他错误处理逻辑...
return Promise.reject(error);
}
)
export default service
避免多次弹出重复提示
当我们进行接口请求的时候,如果请求多个接口都报错的时候,会弹出多个错误提示,这样很不友好,我们需要的是每次只弹出一个错误提示。