// 添加请求拦截器
request.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么
const token = getToken().token
if (token) {
config.headers!.Authorization = `Bearer ${token}`
}
return config
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error)
}
)
// 添加响应拦截器
request.interceptors.response.use(
function (response) {
// 对响应数据做点什么
return response
},
async function (error: AxiosError<{ message: string }>) {
console.dir(error, '99999')
// 无感刷新回答:
// 后台返回401,
// 响应拦截器中处理 => 判断是否是有token
// 如果有 说明token过期了 => 尝试用refresh_token 发请求刷新token
// 刷新成功, 保存到本地以及仓库中 并重新发请求
// 刷新失败, 说明refresh_token 也过期了 则跳转到登录页
// 理解 :用户发起一个请求,
// 情况1:请求成功正常拿到数据,正常渲染
// 情况2: 没有返回结果 说明服务器有误,提示用户
// 情况3: 后端返回401 说明token过期,请求拦截器中判断返回结果是否为401,
// 如果是401则,尝试利用refresh_token发送一个刷新token请求
// 拿回新token 基于新的token在发送上一个响应错误的请求,
// 如果没有拿到新的token 则说明refresh_token也过期,跳转登录页
// 如果本地根本没有token,请直接拦截到登录页
// 对响应错误做点什么
// !----------------情况1:服务器繁忙------------
if (!error.response) {
// 如果没有响应信息
Toast.show({
content: '服务器繁忙,请稍后重试',
duration: 3000,
})
return Promise.reject(error)
}
// !----------------情况2:token过期----------------
const token = getToken()
// 判断是否为401
if (error.response.status === 401) {
// 是的话判断本地有没有refresh_token
// 如果有token 发送请求获取新的token
if (token.refresh_token) {
try {
// 获取新的token
const res = await axios({
method: 'put',
url: baseURL + '/authorizations',
headers: {
Authorization: 'Bearer ' + token.refresh_token,
},
})
// 拿到新token 存入仓库
store.dispatch(
savetoken({
// token为最新获取的token
token: res.data.data.token,
// refresh_token是从本地获取的
refresh_token: token.refresh_token,
})
)
// 存入成功后 重新发送错误请求
return request.request(error.config)
} catch (error) {
// !----------------情况3:refresh_token过期----------------
// 如果失败说明 refresh_token也过期 重新登录
Toast.show({
content: '登录信息过期,请重新登录',
})
// 清除现有的所有的token
store.dispatch(LogOut())
// 携带当前路径 直接跳转
history.replace({
pathname: '/login',
state: {
form: history.location.pathname,
},
})
}
return Promise.reject(error)
} else {
// !----------------情况4:根本没有token----------------
// 如果没有直接跳
Toast.show({
content: '登录认证失效',
})
// 携带当前路径 直接跳转
history.replace({
pathname: '/login',
state: {
form: history.location.pathname,
},
})
return Promise.reject(error)
}
}
// 提示用户错误信息
Toast.show({
content: error.response?.data.message,
duration: 3000,
})
return Promise.reject(error)
}
)
最后修改:2022 年 05 月 02 日
© 允许规范转载
END
本文作者: 鼎g
文章标题:React、Vue项目中Token无感刷新原理-实用大多数项目
本文地址:https://zhougewk8.cn/11.html
版权说明:若无注明,本文皆Dg's Blog-专注健康快乐每一天原创,转载请保留文章出处。
文章标题:React、Vue项目中Token无感刷新原理-实用大多数项目
本文地址:https://zhougewk8.cn/11.html
版权说明:若无注明,本文皆Dg's Blog-专注健康快乐每一天原创,转载请保留文章出处。