axios拦截器

437 阅读2分钟

1、 用法

一、 拦截器介绍

一般在使用axios时,会用到拦截器的功能,一般分为两种:请求拦截器、响应拦截器。

  1. 请求拦截器
    在请求发送前进行必要操作处理,例如添加统一cookie、请求体加验证、设置请求头等,相当于是对每个接口里相同操作的一个封装;
  2. 响应拦截器
    同理,响应拦截器也是如此功能,只是在请求得到响应之后,对响应体的一些处理,通常是数据统一处理等,也常来判断登录失效等。

二、 Axios实例

import axios from 'axios'

// 设置请求拦截器
axios.interceptors.request.use(
  config => {
    // console.log(config) // 该处可以将config打印出来看一下,该部分将发送给后端(server端)
    config.headers.Authorization = store.state.token
    return config // 对config处理完后返回,下一步将向后端发送请求
  },
  error => { // 当发生错误时,执行该部分代码
    // console.log(error) // 调试用
    return Promise.reject(error)
  }
)

// 定义响应拦截器 -->token值无效时,清空token,并强制跳转登录页
axios.interceptors.response.use(function (response) {
  // 响应状态码为 2xx 时触发成功的回调,形参中的 response 是“成功的结果”
  return response
}, function (error) {
  // console.log(error)
  // 响应状态码不是 2xx 时触发失败的回调,形参中的 error 是“失败的结果”
  if (error.response.status === 401) {
    // 无效的 token
    // 把 Vuex 中的 token 重置为空,并跳转到登录页面
    // 1.清空token
    store.commit('updateToken', '')
    // 2.跳转登录页
    router.push('/login')
  }
  return Promise.reject(error)
})

2、原理

// 先构造一个对象 存放拦截器
axios.interceptors = {
  request: [],
  response: []
};

// 注册请求拦截器
axios.useRequestInterceptor = (resolved, rejected) => {
  axios.interceptors.request.push({ resolved, rejected });
};

// 注册响应拦截器
axios.useResponseInterceptor = (resolved, rejected) => {
  axios.interceptors.response.push({ resolved, rejected });
};

// 运行拦截器
axios.run = config => {
  const chain = [
    {
      resolved: axios,
      rejected: undefined
    }
  ];

  // 把请求拦截器往数组头部推
  axios.interceptors.request.forEach(interceptor => {
    chain.unshift(interceptor);
  });

  // 把响应拦截器往数组尾部推
  axios.interceptors.response.forEach(interceptor => {
    chain.push(interceptor);
  });

  // 把config也包装成一个promise
  let promise = Promise.resolve(config);

  // 暴力while循环解忧愁
  // 利用promise.then的能力递归执行所有的拦截器
  while (chain.length) {
    const { resolved, rejected } = chain.shift();
    promise = promise.then(resolved, rejected);
  }

  // 最后暴露给用户的就是响应拦截器处理过后的promise
  return promise;
};

测试

axios.useRequestInterceptor(config => {
  return {
    ...config,
    extraParams1: "extraParams1"
  };
});

axios.useRequestInterceptor(config => {
  return {
    ...config,
    extraParams2: "extraParams2"
  };
});

axios.useResponseInterceptor(
  resp => {
    const {
      extraParams1,
      extraParams2,
      result: { code, message }
    } = resp;
    return `${extraParams1} ${extraParams2} ${message}`;
  },
  error => {
    console.log("error", error);
  }
);


(async function() {
  const result = await axios.run({
    message: "message1"
  });
  console.log("result1: ", result);
})();
(async function() {
  const result = await axios.run({
    message: "message1"
  });
  console.log("result1: ", result);
})();

欢迎关注我的前端自检清单,我和你一起成长