说一下逻辑
//登录成功后的返回数据
{
access_token:'当前调接口使用的token',
refresh_token:'刷新用的token',
}
主要代码
axios.js
// 是否正在刷新
window.isRefreshing = false;
// 重试队列 每一项都是一个待执行待函数
let requests = [];
request.interceptors.response.use((response) => {
return response
}, errorHandler)
const errorHandler = (error) => {
if (error.response) {
// 判断http状态是否是401
if (error.response.status === 401) {
console.log(window.isRefreshing)
if (!window.isRefreshing) {
window.isRefreshing = true;
// 调接口,刷新token .
// !!! 没有return 页面拿不到再次请求的数据
return store.dispatch('RefreshToken').then(() => {
window.isRefreshing = false;
requests.forEach(cb => cb())
requests = []; //注意要清空
// 再发请求
return request(error.config);
}).catch((err) => {
window.isRefreshing = false;
})
} else {
// 正在刷新token ,把后来的接口缓冲起来
console.log(error.config)
return new Promise((resolve) => {
requests.push(() => {
resolve(request(error.config));
});
})
}
} else if (error.response.status === 403) {
Message({
message: '暂无权限',
duration: 2000
})
} else {
Message({
message: '网络错误',
duration: 2000
})
}
}
return Promise.reject(error)
}
store.js
actions: {
// 刷新token
RefreshToken({
commit,
state
}) {
/*
* 4013 refresh_token已过期 || 无效token(refresh_token值为空)
* 3015 未经授权
*/
return new Promise((resolve, reject) => {
api.refreshToken().then((res) => {
console.log(res.data.code)
if (res.data.code == 1) {
commit('SET_TOKEN', res.data.data.access_token)
commit('SET_RETOKEN', res.data.data.refresh_token)
Message({
message: '登录成功',
type: 'success',
duration: 2000
})
resolve()
} else if (res.data.code == 4013) {
commit('removeUser', '')
window.localStorage.removeItem("vuex");
//判断是否需要跳转首页
if(router.currentRoute.meta.auth == true){
router.replace({
path: '/'
})
}
store.dispatch('getAccessToken').then(res => {
console.log(res)
resolve()
})
} else {
commit('removeUser', '')
window.localStorage.removeItem("vuex");
store.dispatch('getAccessToken')
Message({
message: res.data.message,
type: 'error',
duration: 2000
})
router.push({
path: '/'
})
reject()
}
}).catch((err) => {
reject(err)
}).finally(() => {
})
})
},
// 获取默认token
getAccessToken({
commit,
state
}) {
return new Promise((resolve) => {
api.getAccessToken().then((res) => {
if (res.data.code == 200) {
commit('SET_TOKEN', res.data.data.access_token)
commit('SET_RETOKEN', res.data.data.refresh_token)
resolve(res)
}
})
})
},
}
封装axios.js请求
//默认touken
getAccessToken(params) {
return axios.get(`${api}/getToken`,params);
},
refreshToken(params) {
return axios.post(`${api}/refresh`,params,{
headers:{
'httpRefresh':'refresh_token' // 请求前设置请求头的判断条件
}
});
},
控制台截图