问题一:如何防止多次刷新token
通过设置一个变量isRefreshing 去控制是否在刷新token的状态
if (!isRefreshing) {
isRefreshing = true
return refreshToken().then((data:any) => {
setToken(data.token_type+' '+data.access_token);
//存储token过期时换取新token值
localStorage.setItem('refresh-token',data.refresh_token)
// 刷新token成功后重新发送原来的请求
return service(response.config);
}).catch((error) => {
// 刷新token失败,跳转到登录页
// message.error(res.message)
message.error('您长时间未登录,请重新登录!')
goLogout();
return Promise.reject(error);
}).finally(()=>{
isRefreshing = false;
});
}
问题二:同时发起两个或者两个以上的请求时,其他接口怎么解决
当第二个过期的请求进来是,token正在刷新,这个时候我们可以先把这个请求存到一个数组队列中,想办法让这个请求处于等待中,一直等到刷新的token后再逐个重试清空请求队列,那么如何让这个请求处于等待中呢?我们可以借助于Promise。将请求存进队列中后,同时返回一个Promise,让这个请求一直处于等待状态,此时这个请求就会一直等,只要我们不执行resolve,这个请求就会一直在等待、当刷新请求的接口返回来后,在调用resolve,逐个重试
service.interceptors.response.use(
(response: any) => {
//console.log('封装地方的response',response)
//removePending( response.config );
const res = response.data;
// 后端status错误判断
if (response.status == 200) {
if(response.data.hasOwnProperty('code')){
if (res.code == 200) {
return Promise.resolve(res);
} else if (res.code == 401) {
if(getToken()&&!isRefreshing){
isRefreshing= true;
removeToken()
// token过期,调用刷新token的接口
return refreshToken().then((data:any) => {
setToken(data.token_type+' '+data.access_token);
//存储token过期时换取新token值
localStorage.setItem('refresh-token',data.refresh_token)
//token刷新后将数组的方法重新执行
requests.forEach((cb:any)=>cb())
requests=[]
// 刷新token成功后重新发送原来的请求
return service(response.config);
}).catch((error) => {
// 刷新token失败,跳转到登录页
// message.error(res.message)
message.error('您长时间未登录,请重新登录!')
goLogout();
return Promise.reject(error);
}).finally(()=>{
isRefreshing= false;
});
}else{
//message.error(res.message)
// 返回未执行 resolve 的 Promise
return new Promise(resolve => {
// 用函数形式将 resolve 存入,等待刷新后再执行
requests.push(() => {
resolve(service(response.config))
})
})
// goLogout()
// return Promise.reject(res);
}
}else if (res.code == 501) {
message.error(res.data)
return Promise.reject(res);
} else if (res.code == 500) {
if(!response.request.responseURL.includes('/admin/tender/token/refresh')){
message.error(res.message)
return Promise.resolve(res);
}else{
return Promise.reject(res);
}
}else {
// 错误状态码处理
message.error(res.message)
return Promise.reject(res);
}
}else{
//这里针对excel的文件流导出
return Promise.resolve(response);
}
} else {
errorMessage(response)
return Promise.reject();
}
},
(error: any) => {
// Http错误状态码处理
// return Promise.reject(error);
if (error && error.response) {
// 1.公共错误处理
// 2.根据响应码具体处理
errorMessage(error.response)
} else {
// 超时处理
if (JSON.stringify(error).includes('timeout')) {
// Message.error('服务器响应超时,请刷新当前页')
error.message = '服务器响应超时,请刷新当前页'
} else {
error.message = '连接服务器失败'
}
message.warning(error.message)
}
}
);
标签:return,res,vue3,response,token,error,message,无感 From: https://www.cnblogs.com/menglm/p/18400480