相关推荐recommended
Vue 拦截器原理和详细使用
作者:mmseoamin日期:2023-12-02

拦截器原理和作用

  • 首先拦截器在src/utils/request.js 文件中,拦截器分为请求拦截器和响应拦截器。

  • 页面中的每一个请求都会经过请求拦截和响应拦截,所以一般在这个文件进行操作。

  • 这一文件一般引入axios,vuex,Message,router 和相关方法 ,基地址+拦截器。

  • 请求拦截器:Token的主动处理 给每一个请求添加请求头token 对请求异常抛出。

  • 响应拦截器:简化axios默认加了一层的data Token被动处理 对请求异常抛出。


    最简化版本

    // 导入axios
    import axios from 'axios'
    // 基地址
    const service = axios.create({
      baseURL: process.env.VUE_APP_BASE_API,
      // 5秒超时
      timeout: 10000
    })
    // 请求拦截
    request.interceptors.request.use(
      config => {
        return config
      },
      error => {
        return Promise.reject(error)
      }
    )
    // 响应拦截
    request.interceptors.response.use(
      res => {
        return res
      },
      // 响应错误的代码写这里
      error => {
        return Promise.reject(error)
      }
    )
    // 暴露副本
    export default service

    下面是实际开发中使用

    注意:

    当我们使用axios时候,他会给我们默认加一层data。这样我们取数据的时候就会比较增加无效代码,所以我们可以在数据响应的时候判断,给他人为的去掉一层,如下面判断 return data ,这样就可以直接res.data.变量

    还有一个是token 处理 这里包含了主动处理:登录时候存一个时间,判断这个时间,超过就调用登出方法,提示信息,打回到登录页。被动处理:异常的时候判断一下,如果是和后端规定好的token过期状态码(比如401),就调用登出方法,提示信息,打回到登录页。

    基地址最好不要写死写变量名,这样我们就可以通过改环境文件快速更改地址。

    // 导入axios
    import axios from 'axios'
    // 导入提示信息
    import { Message } from 'element-ui'
    // 导入vuex
    import store from '@/store'
    // 导入路由
    import router from '@/router'
    // 导入获取时间和token的工具函数
    import { getToken, getTokenTime } from '@/utils/auth'
    // 基地址
    const service = axios.create({
      baseURL: process.env.VUE_APP_BASE_API,
      // 5秒超时
      timeout: 10000
    })
    // 请求拦截
    // 添加一个service的请求拦截器
    service.interceptors.request.use(
      async config => {
        // config就是本次发请求的信息
        // 判断有没有token
        if (store.state.user.token) {
          // token失效的主动处理
          // 获取一下记录token的时间
          let start = getTokenTime()
          // 获取一下当前时间
          let now = Date.now()
          // 算出时间差
          let hour = (now - start) / 1000 / 3600
          // 判断是否超过1小时
           if (hour >= 1) {
             // 代表token过期
             await store.dispatch('user/logout')
             Message.error('token已过期,请重新登录')
             router.push('/login')
          // return代表不往下执行,所以这个请求不会发送
             return
           }
           config.headers.Authorization = 'Bearer ' + getToken()
          config.headers['Bearer'] = getToken()
          // config.headers.tenantid =  getTenantId ()
        }
        // 发送请求
        return config
      },
      error => {
        return Promise.reject(error)
      }
    )
    // 响应拦截
    service.interceptors.response.use(
      res => {
        // axios默认加了一层data
        // 这个res包括这个请求响应回来的所有信息
        // 所有的接口请求都会回到这里
        // 获取到本次请求得到的数据
        const data = res.data
        // 会帮所有的请求打印
        // console.log(data);
        // 判断本次请求是否成功
        if (data.code === 200 || data.code == 0) {
          // 如果响应成功,则正常给他返回数据
          return data
        } else {
          // 证明失败,我们需要让外面的catch被调用
          // 要让catch被调用,就要手动抛出一个错误,并把服务器返回的消息抛回去
          Message.warning(data.message || data.msg)
          return Promise.reject(data.message)
        }
      },
      async error => {
        // token失效的被动处理
        console.log(error)
        if (error.response.data.code === 401) {
          await store.dispatch('user/logout')
          Message.warning('登录状态过期,请重新登录!')
          router.push('/login')
        } else {
          return Promise.reject(error)
        }
      }
      // error => {
      //   return Promise.reject(error)
      // }
    )
    // 暴露副本
    export default service

    浏览器存取

    Vue 拦截器原理和详细使用,img,第1张


    总结:

    经过这一趟流程下来相信你也对 Vue 拦截器原理和详细使用 有了初步的深刻印象,但在实际开发中我 们遇到的情况肯定是不一样的,所以我们要理解它的原理,万变不离其宗。加油,打工人!

    什么不足的地方请大家指出谢谢 -- 風过无痕