• axios 请求拦截器&响应拦截器与router的导航守卫


    一、 拦截器介绍

    一般在使用axios时,会用到拦截器的功能,一般分为两种:请求拦截器、响应拦截器。
    1.请求拦截器
    在请求发送前进行必要操作处理,例如添加统一cookie、请求体加验证、设置请求头等,相当于是对每个接口里相同操作的一个封装;

    2.响应拦截器
    同理,响应拦截器也是如此功能,只是在请求得到响应之后,对响应体的一些处理,通常是数据统一处理等,也常来判断登录失效等。

    二、 Axios实例
    1.创建axios实例

    // 引入axios
    import axios from 'axios'
     
    // 创建实例
    let instance = axios.create({
        baseURL: 'xxxxxxxxxx',
        timeout: 15000  // 毫秒
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.baseURL设置:

    let baseURL;
    if(process.env.NODE_ENV === 'development') {
        baseURL = 'xxx本地环境xxx';
    } else if(process.env.NODE_ENV === 'production') {
        baseURL = 'xxx生产环境xxx';
    }
     
    // 实例
    let instance = axios.create({
        baseURL: baseURL,
        ...
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.修改实例配置的三种方式
    // 第一种:局限性比较大
    axios.defaults.timeout = 1000;
    axios.defaults.baseURL = ‘xxxxx’;

    // 第二种:实例配置

    let instance = axios.create({
        baseURL: 'xxxxx',
        timeout: 1000,  // 超时,401
    })
    // 创建完后修改
    instance.defaults.timeout = 3000
     
    // 第三种:发起请求时修改配置、
    instance.get('/xxx',{
        timeout: 5000
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这三种修改配置方法的优先级如下:请求配置 > 实例配置 > 全局配置

    三、 配置拦截器

    // 请求拦截器
    instance.interceptors.request.use(req=>{}, err=>{});
    // 响应拦截器
    instance.interceptors.reponse.use(req=>{}, err=>{});
    
    • 1
    • 2
    • 3
    • 4

    从上可以看出,instance依然是第二步中创建的实例,然后对其进行拦截,请求用request,响应用reponse,二者都有两个配置项,一个是成功配置,一个是error配置。

    1.请求拦截器

    // use(两个参数)
    axios.interceptors.request.use(req => {
        // 在发送请求前要做的事儿
        ...
        return req
    }, err => {
        // 在请求错误时要做的事儿
        ...
        // 该返回的数据则是axios.catch(err)中接收的数据
        return Promise.reject(err)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.响应拦截器

    // use(两个参数)
    axios.interceptors.reponse.use(res => {
        // 请求成功对响应数据做处理
        ...
        // 该返回的数据则是axios.then(res)中接收的数据
        return res
    }, err => {
        // 在请求错误时要做的事儿
        ...
        // 该返回的数据则是axios.catch(err)中接收的数据
        return Promise.reject(err)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.常见错误码处理(error)
    axios请求错误时,可在catch里进行错误处理。

    axios.get().then().catch(err => {
        // 错误处理
    })
    
    • 1
    • 2
    • 3

    但实际开发过程中,一般在请求/响应拦截器中统一做错误处理,有特殊接口的话做单独的catch错误处理

    四、 axios请求拦截器的案例
    axios请求发送之前,拦截请求,在请求中判断是不是post提交,是就做出处理

    import axios from 'axios'
     
    // 创建一个axios实例
    const axios_instance = axios.create()
    //设置axios拦截器: 请求拦截器
    axios_instance.interceptors.request.use(config => {
      //得到请求方式和请求体数据
      const {method,data} = config;
      if(method.toLowerCase() == 'post' && typeof data == 'object'){
         config.data = qs.stringify(data)
      }
      config.headers['X-Token'] = getToken()
      return config;
    }, err => {
      // 请求未成功发出,如:没有网络...
      return Promise.reject(err)
    })
    //设置axios拦截器: 响应拦截器
    axios_instance.interceptors.response.use(res => {
      // 成功响应的拦截
      const data = res.data;
      const code = data.code;
    
      if(code == 200  ){
        return data;
      }else{
        return Promise.reject(data);
      }
    }, err =>{
      //请求的地址错误 会进入这里
      console.log(err)
      return Promise.reject(err)  
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    导航守卫

    import router from '@/router'
    import store from '@/store'
    import { Message } from 'element-ui'
    import NProgress from 'nprogress'
    import 'nprogress/nprogress.css'
    import { getToken } from '@/assets/js/utils/token'
    
    const whiteList = ['/login']
    
    router.beforeEach(async(to, from, next) => {
    
      NProgress.start()
    
      const hasToken = getToken()
      if (hasToken) {
        if (to.path === '/login') {
          next({ path: '/' })
          NProgress.done()
        } else {
          const hasGetUserInfo = store.getters.name
          if (hasGetUserInfo) {
            next()
          } else {
            try {
              await store.dispatch('user/getInfo')
              next()
            } catch (error) {
              console.log(error)
              await store.dispatch('user/resetToken')
              Message.error(error || 'Has Error')
              next(`/login?redirect=${to.path}`)
              NProgress.done()
            }
          }
        }
      } else {
        if (whiteList.indexOf(to.path) !== -1) {
          next()
        } else {
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    })
    
    router.afterEach(() => {
      NProgress.done()
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
  • 相关阅读:
    虚拟机的网络模式
    二叉树 | 构造二叉树 | 中序&后序、前序&中序遍历序列、最大二叉树 | leecode刷题笔记
    听力检测为什么要在标准化的隔声屏蔽系统中进行?
    别再到处乱放配置文件了!我司使用 7 年的这套解决方案,稳的一秕
    讲解 java ThreadLocal
    JAVA 0基础 算数运算符
    网工记背命令(6)----链路聚合配置
    麒麟v10服务器安装vnc
    《Java》【速学】对象-多态
    建木v2.6.0发布
  • 原文地址:https://blog.csdn.net/m0_67401055/article/details/126012227