axios响应拦截器处理401
1. 返回401的情况
1、 未登录用户需要做一些需要权限才能做的操作。
2、 登录用户的accessToken过期了(accessToken的有效期由后端同学来决定)。
2. refreshToken的作用
当accessToken的有效期过了之后,可以使用refreshToken请求一个接口(需要把refreshToken传过去),并返回一个新的accessToken(一般有效期是2个小时),以替换过期的那个accessToken。
3. request响应拦截401处理
对于某次请求A,如果是401错误,有以下两种情况:
1、有refreshToken,用refreshToken去请求回新的accessToken
1.1 新accessToken请求成功: 更新本地accessToken ,再发一次请求A
1.2 新accessToken请求失败: 携带请求地址,跳转到登陆页
2、没有refreshToken,说明没有登陆 : 携带请求地址,跳转到登陆页
request响应拦截401代码实现
//响应拦截器
//服务端返回信息 - > [拦截的统一处理] - > 客户端的js获取到信息
service.interceptors.response.use(response => {
return response
}, async error => {
//对请求返回的错误进行处理
let { response } = error
let eror_msg = ''
if (response) {
switch (response.status) {
case 401: // 提示未登录或无权限等
// 对于某次请求A,如果是401错误,有以下两种情况:
// 1、有refreshToken,用refreshToken去请求回新的accessToken
// 1.1 新accessToken请求成功: 更新本地accessToken ,再发一次请求A
// 1.2 新accessToken请求失败: 携带请求地址,跳转到登陆页
// 2、没有refreshToken,说明没有登陆 : 携带请求地址,跳转到登陆页
if (getRefreshToken()) { // 有refreshToken,用refreshToken去请求回新的accessToken
// 1. 请求新accessToken
try {
const res = await axios({
url: process.env.VUE_APP_BASE_API + '/common/accessToken/refresh',
method: 'post',
data: {
refreshToken : getRefreshToken()
}
})
// 2. 保存新token
localStorage.setItem('accessToken', res.data.data.accessToken)
localStorage.setItem('refreshToken', res.data.data.refreshToken)
// 3. 重发请求
// service是上面创建的axios的实例
return service(error.config)
} catch (error) {
$store.dispatch('user/resetToken') // 清除token
const backtoUrl = encodeURIComponent(router.currentRoute.fullPath) // router.currentRoute: 表示当前路由对象
router.push('/login?backto=' + backtoUrl)
Message({
message: '登录失效,请重新登录',
type: 'error',
duration: 3 * 1000,
})
}
} else {
// 去登录页
$store.dispatch('user/resetToken') // 清除token
const backtoUrl = encodeURIComponent(router.currentRoute.fullPath)
router.push('/login?backto=' + backtoUrl)
Message({
message: '登录失效,请重新登录',
type: 'error',
duration: 3 * 1000,
})
}
break;
case 400:
eror_msg = '网络异常400'
break
case 404:
eror_msg = '请求错误404'
break
case 405:
eror_msg = '请求方式错误405'
break
case 500:
eror_msg = '网络错误500'
break
case 502:
eror_msg = '服务器错误502'
break
default:
break
}
if(error.includes("timeout")) {
eror_msg = '请求超时'
}
if (!configG.noTip && response.status !== 401) {
Message({
message: eror_msg,
type: 'error',
duration: 5 * 1000,
})
}
} else {
//服务器连结果都没有返回
if (!window.navigator.onLine) {
//断网处理:跳转断网页面/提示网络错误等等
eror_msg = '网络错误'
return
}
return Promise.reject(eror_msg)
}
}
)