axios响应拦截器处理401

2,290 阅读2分钟

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)
    }
  }
)