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是依赖接口返回的话,写在拦截器就可能会发起多次请求,造成请求浪费。

相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学3 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端