当前位置: 首页 > article >正文

axios拦截器底层实现原理

Axios 的拦截器通过内部的Promise 链实现了对请求和响应的拦截与修改。了解其底层原理需要深入到 Axios 源码中,特别是其请求发起和响应处理的逻辑。

Axios 拦截器实现流程

  1. 拦截器队列
    Axios 在内部维护了两个拦截器队列:requestresponse。当开发者通过 interceptors.request.useinterceptors.response.use 注册拦截器时,拦截器会被存入队列。

  2. Promise 链
    每次调用 Axios 实例发起请求时,会依次将拦截器队列中的函数(请求/响应拦截器)和实际的请求函数组成一个 Promise 链。

  3. 执行顺序

    • 请求拦截器按注册的顺序执行。
    • 响应拦截器按注册的顺序逆序执行。

核心源码分析

以下是 Axios 源码的关键部分,用于理解拦截器的实现。

1. 拦截器管理

Axios 内部的 InterceptorManager 类用于管理拦截器:

function InterceptorManager() {
  this.handlers = [];
}

// 注册拦截器
InterceptorManager.prototype.use = function use(fulfilled, rejected) {
  this.handlers.push({
    fulfilled: fulfilled, // 成功处理函数
    rejected: rejected,   // 失败处理函数
  });
  return this.handlers.length - 1; // 返回拦截器的索引
};

// 移除拦截器
InterceptorManager.prototype.eject = function eject(id) {
  if (this.handlers[id]) {
    this.handlers[id] = null; // 将对应的拦截器置为 null
  }
};

InterceptorManager 的核心功能是管理拦截器的添加和删除,所有的拦截器函数存储在 handlers 数组中。


2. 请求的 Promise 链构建

当调用 axios.request(config) 时,会构建一个基于拦截器的 Promise 链:

Axios.prototype.request = function request(config) {
  // 初始化配置
  config = config || {};

  // 将实际请求函数添加到链末尾
  let promise = Promise.resolve(config);

  // 构建拦截器链
  const chain = [];

  // 添加请求拦截器(顺序)
  this.interceptors.request.handlers.forEach((interceptor) => {
    if (interceptor !== null) {
      chain.push(interceptor.fulfilled, interceptor.rejected);
    }
  });

  // 添加实际的请求函数
  chain.push(dispatchRequest, undefined);

  // 添加响应拦截器(逆序)
  this.interceptors.response.handlers.forEach((interceptor) => {
    if (interceptor !== null) {
      chain.push(interceptor.fulfilled, interceptor.rejected);
    }
  });

  // 执行链条中的每个函数
  while (chain.length) {
    promise = promise.then(chain.shift(), chain.shift());
  }

  return promise;
};

在上面的实现中:

  • dispatchRequest 是 Axios 实际发起网络请求的函数。
  • 请求拦截器按注册的顺序加入链。
  • 响应拦截器按逆序加入链。
  • 最终,Promise 链依次执行每个拦截器和请求逻辑。

3. 实际请求的实现

dispatchRequest 负责发起 HTTP 请求并返回响应:

function dispatchRequest(config) {
  // 检查是否已取消请求
  if (config.cancelToken) {
    config.cancelToken.throwIfRequested();
  }

  // 发起请求
  return xhrAdapter(config).then(
    (response) => {
      return response;
    },
    (error) => {
      return Promise.reject(error);
    }
  );
}

xhrAdapter 是默认的适配器,用于在浏览器环境中通过 XMLHttpRequestfetch 发起请求。


工作流程总结

  1. 注册拦截器
    开发者通过 interceptors.request.useinterceptors.response.use 向 Axios 的拦截器队列中添加拦截函数。

  2. 发起请求
    调用 axios(config) 时,Axios 会根据请求拦截器、实际请求函数和响应拦截器构建一个 Promise 链。

  3. 执行链条
    按以下顺序依次执行:

    • 请求拦截器:按注册顺序执行。
    • 实际的请求函数:发送 HTTP 请求。
    • 响应拦截器:按注册顺序逆序执行。
  4. 返回结果
    Promise 链最终返回请求的结果或抛出错误,供调用者处理。


图示说明

请求拦截器1 --> 请求拦截器2 --> dispatchRequest --> 响应拦截器2 --> 响应拦截器1
  • 请求拦截器按顺序执行请求拦截器1 → 请求拦截器2
  • 响应拦截器按逆序执行响应拦截器2 → 响应拦截器1

Axios 拦截器的特点

  1. 链式结构:通过 Promise 链灵活地插入和执行拦截器。
  2. 易扩展:通过 InterceptorManager 动态注册、移除拦截器。
  3. 一致性:无论请求还是响应,拦截器均可统一添加逻辑。

通过上述机制,Axios 实现了强大且灵活的拦截器功能,开发者可以轻松扩展请求和响应的处理逻辑。


http://www.kler.cn/a/461020.html

相关文章:

  • 感知机参数更新策略
  • mask-R-cnn模型详解
  • AcWing练习题:差
  • .net core 线程锁,互斥锁,自旋锁,混合锁
  • 使用Docker部署最新版JupyterHub
  • 【大模型】wiki中文语料的word2vec模型构建
  • 基于SpringBoot+Vue的旅游推荐系统
  • [pdf、epub]260道《软件方法》强化自测题业务建模需求分析共216页(202412更新)
  • Doris安装部署
  • 实现单例模式的五种方式
  • jQuery学习笔记1
  • 无人机任务载荷系统之电子对抗技术!
  • 使用PyTorch实现的二分类模型示例,综合了CNN、LSTM和Attention技术
  • MyBatis-Plus 中的分页插件配置
  • 在C++中,dynamic_cast是一种用于在类的继承体系中进行安全向下转型
  • 搭建ZooKeeper分布式集群
  • 2、单片机、CC2530、zigbee期末考试选择、填空题含答案
  • 如何确保Kafka集群的高可用?
  • Cursor小试1.生成一个网页的接口请求工具
  • Django 管理界面实现自动提交和动态字段选项
  • 鸿蒙HarmonyOS应用开发 探索 HarmonyOS Next-从开发到实战掌握 HarmonyOS Next 的分布式能力
  • C++中宏的使用方法
  • AI同传的崛起:人工同传还能坚持多久?
  • 股市学习 seekingalpha tradingview
  • OpenAI 的 o3 — AGI 还是闪亮的幻影?
  • 信息安全管理:网络安全