axios适配器拦截请求

什么是axios

Axios 是一个基于 Promise 的 HTTP 客户端,可以用于浏览器和 Node.js 中。通过 Axios,我们可以在浏览器中发送 XMLHttpRequests,在 Node.js 中发送 http 请求。在某些情况下,我们可能需要拦截请求或响应,以便在请求发送或响应返回之前对其进行处理。这就是 Axios 适配器的作用。

拦截器 Interceptors

定义:在发起请求或做出响应前对请求进行拦截。

javascript 复制代码
axios.interceptors.request.use(function (config) { 
    // 在发送请求之前做些什么 
    return config; 
}, function (error) { 
    // 对请求错误做些什么 
    return Promise.reject(error); 
});

axios.interceptors.response.use(function (response) { 
    // 2xx 范围内的状态码都会触发该函数。 
    // 对响应数据做点什么 
    return response; 
}, function (error) { 
    // 超出 2xx 范围的状态码都会触发该函数。 
    // 对响应错误做点什么 
    return Promise.reject(error); 
});

还可以给axios的实例添加自定义拦截器

php 复制代码
const instance = axios.create(); 
instance.interceptors.request.use(function () {/*...*/});

通常地,我们可以在拦截器里加上一些自己的通用处理逻辑, 比如:

  • 请求参数整合,转换
  • 添加自定义headers
  • 去掉无用参数
  • 根据业务返回码处理响应体
  • 统一处理每个请求的请求异常和响应异常
  • ....

适配器 Adapter

适配器允许用户自定义处理请求

它的配置项是在请求配置里的adapter里,它需要返回一个promise

javascript 复制代码
// 返回一个 promise 并提供一个有效的响应 (参见 lib/adapters/README.md)。 
adapter: function (config) { 
    /* ... */ 
    return Promise
},

如果用户没有给axios或者axios的实例配置适配器,那么它将使用它默认的适配器

从源码可以看出来,每次请求都会先经过适配器,适配器会返回一个promsie,然后再真正的读取适配器发起的请求得到真正的请求结果

那么可以得出,拦截器与适配器的一些区别了。

拦截器与适配器的区别

  • 针对单个请求,拦截器可以配置多个拦截,但是适配器只能配置一个
  • 拦截器无法真正拦截请求的发起和返回,但是适配器可以直接拦截请求的发起,直到满足某些条件才真正发起请求
  • ...

使用适配器执行阻塞请求

首先在axios的适配器里面配置一个拦截器

typescript 复制代码
  axios.create({
      baseURL,
      timeout,
      headers,
      adapter: config => {
        return requestEnhancer(config) as Promise<any>;
      }
 })

适配器对请求进行拦截

javascript 复制代码
function requestEnhancer(config: AxiosRequestConfig) {
  // 需要获取axios.defaults.adapter因为这个适配器是axios底层实现
  const adapter = axios.defaults.adapter as AxiosAdapter;
  // 此处模拟需要获得ticket才可以没有满足的条件统一进入等待处理
  let hasTicket = false;
  const whiteList = ['/getTicket']

  const request = (myConfig?: AxiosRequestConfig) => {
    // 如果ticket是依赖后端处理的话,此处还需要配置一个请求白名单去获取ticket
    // 否则获取ticket的请求将永远发不出去,一直等待get-ticket的返回
    if (hasTicket || whiteList.includes(myConfig.url)) {
      return adapter(config)
    }  else {
      // 通过发布订阅模式监听ticket的返回
      bus.on('get-ticket', (ticket) => {
        // 可以重新配置axiosConfig,由于此处是等待某个字段满足请求
        // 一旦字段满足了请求就需要再调一次request方法使其真正调用adapter发起请求并进行处理
        // 此处就可以将ticket放到请求头
        // myConfig.headers['ticket'] = ticket
        request(myConfig);
      })
    }   
  };


  return request(config);
}

这样处理后,如果前置字段ticket没有值的时候,接口永远不能发起请求,必须要等待ticket有值返回后,后续接口才能真正发起请求,如此便实现了阻塞请求。

总结

相比于拦截器,适配器能真正的阻塞请求的发起和响应,并且对于前置字段依赖的处理更加优雅,如果涌拦截器去处理前置字段依赖,那么在拦截器去处理的话,那么就可能会对该前置字段进行了多次的冗余处理,比如上述的ticket是依赖接口返回的话,写在拦截器就可能会发起多次请求,造成请求浪费。

相关推荐
德育处主任9 分钟前
p5.js 掌握圆锥体 cone
前端·数据可视化·canvas
mazhenxiao11 分钟前
qiankunjs 微前端框架笔记
前端
无羡仙18 分钟前
事件流与事件委托:用冒泡机制优化前端性能
前端·javascript
秃头小傻蛋19 分钟前
Vue 项目中条件加载组件导致 CSS 样式丢失问题解决方案
前端·vue.js
CodeTransfer19 分钟前
今天给大家搬运的是利用发布-订阅模式对代码进行解耦
前端·javascript
阿邱吖20 分钟前
form.item接管受控组件
前端
韩劳模22 分钟前
基于vue-pdf实现PDF多页预览
前端
鹏多多23 分钟前
js中eval的用法风险与替代方案全面解析
前端·javascript
KGDragon23 分钟前
还在为 SVG 烦恼?我写了个 CLI 工具,一键打包,性能拉满!(已开源)
前端·svg
LovelyAqaurius23 分钟前
JavaScript中的ArrayBuffer详解
前端