axios拦截函数封装

一、路由拦截

const routes = [
    {
        path: '/',
        name: '/',
        component: Index
    },
    {
        path: '/repository',
        name: 'repository',
        meta: {
            requireAuth: true,  // 添加该字段,表示进入这个路由是需要登录的
        },
        component: Repository
    },
    {
        path: '/login',
        name: 'login',
        component: Login
    }
];
router.beforeEach((to, from, next) => {
    if (to.meta.requireAuth) {  // 判断该路由是否需要登录权限
        if (store.state.token) {  // 通过vuex state获取当前的token是否存在
            next();
        }
        else {
            next({
                path: '/login',
                query: {redirect: to.fullPath}  // 将跳转的路由path作为参数,登录成功后跳转到该路由
            })
        }
    }
    else {
        next();
    }
})

每个钩子方法接收三个参数:

  • to: Route: 即将要进入的目标 路由对象
  • from: Route: 当前导航正要离开的路由
  • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
  • next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
  • next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
  • next(‘/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。

拦截器

axios拦截请求:首次登录的请求不带token,之后都带上token
axios拦截响应:请求时报错的部分处理封装函数

import stores from 'store'
import axios from 'axios'
import { Message } from 'element-ui'
import router from './router'
// 拦截请求
axios.interceptors.request.use(
  config => {
    // POST || PUT || DELETE请求时先格式化data数据
   // 这里需要引入第三方模块qs
   if (
     config.method.toLocaleUpperCase() === 'post' ||
     config.method.toLocaleUpperCase() === 'put' ||
     config.method.toLocaleUpperCase() === 'delete'
   ) {
     config.data = qs.stringify(config.data)
   }

    if (stores.get('tokenData')) {
      config.headers.Authorization = `Token ${stores.get('tokenData').token}`
    }
    // console.log(config, '响应数据')
    return config
  },
  err => {
    // console.log(err)
    return Promise.reject(err)
  })

// 拦截响应
axios.interceptors.response.use(
  response => {
    // console.log(response, '响应正确')
    return response
  },
  error => {
    // 此处报错可能因素比较多
    // 1.需要授权处用户还未登录,因为路由段有验证是否登陆,此处理论上不会出现
    // 2.需要授权处用户登登录过期
    // 3.请求错误 4xx
    // 5.服务器错误 5xx
    // 关于鉴权失败,与后端约定状态码为500
    console.log(error.response, '响应错误拦截')
    let text = ''
    if (error.response) {
      text = setResponse(error.response.data)
    } else {
      Message.error({
        message: '响应有误,请联系管理员',
        duration: 1000
      })
    }
    switch (error.response.status) {
      case 403:
        // 一些处理...
        break
      case 404:
        // 一些处理...
        break
      case 500:
        let userData = getUserData()
        if (userData.token === undefined) {
          // 此处为未登录处理
          // 一些处理之后...再去登录页面...
          // router.push({
          //   path: '/login'
          // })
        } else {
          let overdueTime = userData.overdueTime
          let nowTime = +new Date
          if (overdueTime && nowTime > overdueTime) {
            // 此处登录过期的处理
            // 一些处理之后...再去登录页面...
            // router.push({
            //   path: '/login'
            // })
          } else {
            // 极端情况,登录未过期,但是不知道哪儿错了
            // 按需处理吧...我暴力回到了首页
            router.push({
              path: '/'
            })
          }
        }
        break
      case 501:
        // 一些处理...
        break
      default:
        // 状态码辣么多,按需配置...
        break
    }
    return error;
    // return Promise.reject(error.response.data)
  })

function setResponse(jsonObj) {
    for (let key in jsonObj) {
        let element = jsonObj[key]
        if (element.length > 0 && typeof (element) === 'object' || typeof (element) === 'object') {
             // console.log(element)
            setResponse(element)
        } else {
            arr.push(element)
        }
    }
    return arr
}

// 注销
export function removeLogin() {
    stores.remove('tokenData')//移除store里面的缓存
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容