axios拦截器底层实现原理
Axios 的拦截器通过内部的Promise 链实现了对请求和响应的拦截与修改。了解其底层原理需要深入到 Axios 源码中,特别是其请求发起和响应处理的逻辑。
Axios 拦截器实现流程
-
拦截器队列
Axios 在内部维护了两个拦截器队列:request
和response
。当开发者通过interceptors.request.use
或interceptors.response.use
注册拦截器时,拦截器会被存入队列。 -
Promise 链
每次调用 Axios 实例发起请求时,会依次将拦截器队列中的函数(请求/响应拦截器)和实际的请求函数组成一个 Promise 链。 -
执行顺序
- 请求拦截器按注册的顺序执行。
- 响应拦截器按注册的顺序逆序执行。
核心源码分析
以下是 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
是默认的适配器,用于在浏览器环境中通过 XMLHttpRequest
或 fetch
发起请求。
工作流程总结
-
注册拦截器
开发者通过interceptors.request.use
和interceptors.response.use
向 Axios 的拦截器队列中添加拦截函数。 -
发起请求
调用axios(config)
时,Axios 会根据请求拦截器、实际请求函数和响应拦截器构建一个 Promise 链。 -
执行链条
按以下顺序依次执行:- 请求拦截器:按注册顺序执行。
- 实际的请求函数:发送 HTTP 请求。
- 响应拦截器:按注册顺序逆序执行。
-
返回结果
Promise 链最终返回请求的结果或抛出错误,供调用者处理。
图示说明
请求拦截器1 --> 请求拦截器2 --> dispatchRequest --> 响应拦截器2 --> 响应拦截器1
- 请求拦截器按顺序执行:
请求拦截器1 → 请求拦截器2
- 响应拦截器按逆序执行:
响应拦截器2 → 响应拦截器1
Axios 拦截器的特点
- 链式结构:通过
Promise
链灵活地插入和执行拦截器。 - 易扩展:通过
InterceptorManager
动态注册、移除拦截器。 - 一致性:无论请求还是响应,拦截器均可统一添加逻辑。
通过上述机制,Axios 实现了强大且灵活的拦截器功能,开发者可以轻松扩展请求和响应的处理逻辑。
相关文章:
axios拦截器底层实现原理
Axios 的拦截器通过内部的Promise 链实现了对请求和响应的拦截与修改。了解其底层原理需要深入到 Axios 源码中,特别是其请求发起和响应处理的逻辑。 Axios 拦截器实现流程 拦截器队列 Axios 在内部维护了两个拦截器队列:request 和 response。当开发者…...
《类和对象:基础原理全解析(下篇)》
目录 一、类的构造函数的初始化列表1. 初始化列表的使用2. 初始化列表的初始化顺序3. 使用初始化列表的注意事项 二、类的自动类型转换1. 类的自动类型转换的使用2. 关闭类的自动类型转换 三、静态类成员1. 静态成员的特性2. 使用静态成员计算类创建了多少个对象3. 使用静态类成…...
==和===的区别,被坑的一天
在 JavaScript 中, 和 都用于比较两个值,但它们有一个重要的区别: 1. (宽松相等运算符) 进行比较时,会 自动类型转换(也叫做强制类型转换),即如果比较的两个值的类型不同,JavaScr…...
Azure Airflow 中配置错误可能会使整个集群受到攻击
网络安全研究人员在 Microsoft 的 Azure 数据工厂 Apache Airflow 中发现了三个安全漏洞,如果成功利用这些漏洞,攻击者可能会获得执行各种隐蔽操作的能力,包括数据泄露和恶意软件部署。 “利用这些漏洞可能允许攻击者以影子管理员的身份获得…...
【数据结构】链表(2):双向链表和双向循环链表
双向链表(Doubly Linked List) 定义: 每个节点包含三个部分: 数据域。前驱指针域(指向前一个节点)。后继指针域(指向下一个节点)。 支持从任意节点向前或向后遍历。 #define dat…...
鸿蒙开发:了解正则表达式
前言 从给出的文本中,按照既定的相关规则,匹配出符合的数据,其中的规则就是正则表达式,使用正则表达式,可以使得我们用简洁的代码就能实现一定复杂的逻辑,比如判断一个邮箱账号是否符合正常的邮箱账号&…...
【juc】AQS是什么
目录 1. 说明2. 资源共享方式3. 核心思想与实现4. 自定义同步器5. 常用实现类 1. 说明 1.AQS是AbstractQueuedSynchronizer的简称,即抽象的队列式同步器,也可以称作队列同步器。2.它是Java并发包(java.util.concurrent)中的一个重…...
最好用的图文识别OCR -- PaddleOCR(1) 快速集成
最近在项目中遇到了 OCR 的需求,希望能够实现高效而准确的文字识别。由于预算限制,我并未选择商业付费方案,而是优先尝试了开源工具。一开始,我测试了 GOT-OCR2.0,但由于我的 Mac 配置较低,不支持 GPU 运算…...
【最新】17个一站式数据集成平台案例PPT下载(Apache SeaTunnel )
17个Apache SeaTunnel案例下载见附件! 开发篇 1.Apache SeaTunnel——OLAP 引擎的数据动脉 1.1项目定位——EtLT 时代的新一代数据集成平台 1.2Apache SeaTunnel 核心功能 1.3Apache SeaTunnel 在 OLAP 场景下的应用 1.4WhaleTunnel 产品特性 2.教你从头到尾开发一…...
第2章波动光学引论—抓本质,本质必定简单
1波动光学的电磁理论 1.1波动方程 1)波动方程是通过描述波函数随时间和空间的变化来表达波动的传播和演化。 2)一维波动方程: a.一维波动方程描述了沿着一条直线传播的波动。它的一般形式为: ∂u/∂t v ∂u/∂x 其中ÿ…...
基于通义千问2-VL-7B-Instruct模型的微调技术指南
基于通义千问2-VL-7B-Instruct模型的微调技术指南 引言 通义千问2-VL-7B-Instruct 是一个强大的多模态大语言模型,支持文本和图像的联合理解与生成。为了使其在特定任务或领域上表现更优,微调(Fine-tuning)是一个关键步骤。本文将详细介绍如何对通义千问2-VL-7B-Instruct…...
IDEA XML 文件 SQL 提示
首先连接到对应的数据库。Database 里面要填写对应的数据库名称 配置当前项目的 SQL 方言,例如我这里是 MySQL 数据库管理系统,那么就选择 MySQL 此时就有 SQL 语法、表名、字段名等提示信息了...
Node.js 模块系统
Node.js 模块系统 1. 引言 Node.js,作为一个轻量级、高效的服务器端 JavaScript 运行环境,其模块系统是其最核心的特性之一。Node.js 的模块系统允许开发者将代码组织成多个文件,每个文件都是一个模块,这样可以提高代码的可维护性和可重用性。本文将详细介绍 Node.js 的模…...
面试题:@Transactional 注解在自调用情况下会失效原因
Transactional 注解在自调用情况下会失效,这主要是由于 Spring 事务管理的实现机制所导致的。以下是对这一问题的详细解释: 一、Spring 事务管理的实现机制 Spring 的事务管理是基于 AOP(面向切面编程)实现的,它通过…...
KMP 2024 年总结,Kotlin 崛起的一年
2024 Google I/O 上正式官宣了 KMP(Kotlin Multiplatform)项目,它是 Google Workspace 团队的一项长期「投资」项目,由 JetBrains 开发维护和开源的项目,简单来说,JetBrains 主导,Google Worksp…...
super_vlan
Super VLAN产生的背景 就经典的酒店例子来说,若是将101房和102房的网络划分在同一个vlan下面,那么101房出现了一个懂得某些安全技术的大佬,就会使得102房的隐私得到严重的隐患 所以这时我们就需要将二层给隔离开,但又要去保证10…...
Harbor仓库部署安装、向仓库推送,拉取镜像、容器的基础使用(超级详细,非常透彻)
Harbor 环境搭建笔记 作为新手,在搭建 Harbor 环境的过程中,我参考了大量资料,学到了很多宝贵的知识,但也遇到了不少挑战。虽然目前这套环境仅在测试环境中成功运行,但仍有许多细节需要完善。记录这些经验不仅有助于个…...
【论文+源码】一个基于SSM(Spring + Spring MVC + MyBatis)的公寓电能计量系统
为了实现一个基于SSM(Spring Spring MVC MyBatis)的公寓电能计量系统,我们需要创建一个简单的Web应用程序来记录和显示每个公寓的电能使用情况。以下是一个基本的实现示例。 我们将包括以下几个部分: 数据库表设计实体类DAO层…...
开源架构的容器化部署优化版
上三篇文章推荐: 开源架构的微服务架构实践优化版(New) 开源架构中的数据库选择优化版(New) 开源架构学习指南:文档与资源的智慧锦囊(New) 我管理的社区推荐:【青云交社区…...
linux安装redis及Python操作redis
目录 一、Redis安装 1、下载安装包 2、解压文件 3、迁移文件夹 4、编译 5、管理redis文件 6、修改配置文件 7、启动Redis 8、将redis服务交给systemd管理 二、Redis介绍 1、数据结构 ①字符串String ②列表List ③哈希Hash ④集合Set ⑤有序集合Sorted Set 2、…...
万里数据库GreatSQL监控解析
GreatSQL是MySQL的一个分支,专注于提升MGR(MySQL Group Replication)的可靠性及性能。乐维监控平台可以有效地监控GreatSQL,帮助用户及时发现并解决潜在的性能问题。 通过在GreatSQL服务器上安装监控代理,收集数据库性…...
商米电子秤服务插件
概述 SunmiScaleUTS封装商米电子秤服务模块,支持商米旗下S2, S2CC, S2L CC等设备,设备应用于超市、菜市场、水果店等,用于测量商品的重量,帮助实现快捷、准确、公正的交易等一系列商业场景。 功能说明 SDK插件下载 一. 电子秤参数 型号:S2, S2CC, …...
Java-写一个计数器
一个简单的线程安全的计数器实现。我们将使用AtomicInteger来确保计数操作是线程安全的,并 且提供基本的增减和获取计数值的功能。 简单线程安全计数器 import java.util.concurrent.atomic.AtomicInteger;public class Counter {private final AtomicInteger count = new …...
VSCode 终端显示“pnpm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本”
VSCode 终端显示“pnpm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本”VSCode 终端显示“pnpm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本”解决方案: 1.用get-ExecutionP…...
微信小程序 单选多选radio/checkbox 纯代码分享
单选按钮 <radio-group class"radiogroup" bindchange"radioChange"> <label class"radio" wx:for"{{items}}"> <radio value"{{item.name}}" checked"{{item.checked}}" /> {{item.value}} &…...
Visual Studio 2022安装教程
1、下载网址 Visual Studio 2022 IDE安装网址借助 Visual Studio 设计,具有自动完成、构建、调试、测试功能的代码将与 Git 管理和云部署融为一体。https://visualstudio.microsoft.com/zh-hans/vs/ 点击图片所示 双击运行 2、安装 点击C桌面开发(右边…...
批量读取pdf发票中二维码的信息
如下代码Java类: import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.write.builder.ExcelWriterBuilder; import com.alibaba.excel.write.metadata.Writ…...
Apache Hive常见问题
入门问题 什么是Apache Hive? 解释Hive的用途。Hive作为基于Hadoop的数据仓库工具是如何工作的?与传统关系型数据库相比,使用Hive有什么优势? Hive和关系型数据库管理系统(RDBMS)之间的区别是什么&#…...
SpringCloud源码分析-Gateway
Gateway核心原理,请求经过一系列的责任链最后到达服务端。...
基于N-HiTS神经层次插值模型的时间序列预测——cross validation交叉验证与ray tune超参数优化
论文链接:https://arxiv.org/pdf/2201.12886v3 N-HiTS: Neural Hierarchical Interpolation for TimeSeries Forecasting \begin{aligned} &\text{\large \color{#CDA59E}N-HiTS: Neural Hierarchical Interpolation for TimeSeries Forecasting}\\ \end{aligne…...
Windmill 实战:快速构建自动化工作流和用户界面
1. 引言 在当今快节奏的开发环境中,能够快速构建内部工具和自动化工作流的平台变得越来越重要。Windmill 就是这样一个强大的开源开发者基础设施平台,它能够将脚本自动转换为工作流程和用户界面。本文将深入探讨 Windmill 的使用,从安装到实际应用,帮助您了解如何利用这个…...
51c自动驾驶~合集44
我自己的原文哦~ https://blog.51cto.com/whaosoft/12969097 #Towards Generalist Robot Policies 清华大学&字节 | 迈向通用机器人策略:如何选择VLA? 论文标题:Towards Generalist Robot Policies: What Matters in Building Vision…...
设计模式 创建型 工厂模式(Factory Pattern)与 常见技术框架应用 解析
工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种封装对象创建过程的方式,使得对象的创建与使用分离,从而提高了系统的可扩展性和可维护性。 一、核心思想 工厂模式的核心思想是将“实例化对象”的操作与…...
ElasticSearch7.10-分词器
文章目录 分词器1.字符过滤器1.介绍2.过滤html标签3.mappings过滤规则(屏蔽非文明用语)4.正则替换 2.自定义分词器1.代码2.查询 3.中文分词器1.下载ik分词器7.10.0版本(跟es对应)2.应用ik分词器1.进入插件目录下创建一个ik目录2.将…...
MLP、CNN、Transformer 的区别解析
亲爱的小伙伴们😘,在求知的漫漫旅途中,若你对深度学习的奥秘、Java 与 Python 的奇妙世界,亦或是读研论文的撰写攻略有所探寻🧐,那不妨给我一个小小的关注吧🥰。我会精心筹备,在未来…...
Android Camera压力测试工具
背景描述: 随着系统的复杂化和业务的积累,日常的功能性测试已不足以满足我们对Android Camera相机系统的测试需求。为了确保Android Camera系统在高负载和多任务情况下的稳定性和性能优化,需要对Android Camera应用进行全面的压测。 对于压…...
[Qt] 常用控件 | QWidget | “表白程序2.0”
目录 一、控件概述 控件体系的发展阶段: 二、QWidget 核心属性 核心属性概览: 1、enabled 2、Geometry 实例 1: 控制按钮的位置 实例 2: 表白 程序 i、Window Frame 的影响 ii、API 设计理念 iii、Geometry 和 FrameGeometry 的区别 …...
word无法插入svg格式图片
插入后出现这样的窗口,表明word版本低,没有svg这个选项。 因此这就是区别。在b站找升级word视频。...
【UE5 C++课程系列笔记】20——共享指针的简单使用
目录 概念 创建共享指针示例 重设共享指针 共享指针内容转移 概念 共享指针(主要以 TSharedPtr 为例),TSharedPtr 基于引用计数机制来工作,旨在解决对象所有权共享以及确保在合适的时候自动释放对象资源的问题。它允许多个 TS…...
Oracle 数据库 dmp文件从高版本导入低版本的问题处理
当前有个需求是将oracle 19c上的数据备份恢复到oracle 11g上使用。我们通过exp命令远程进行备份,然后通过imp进行恢复时出现IMP-00010: not a valid export file, header failed verification报错。 这是数据库版本问题,在使用exp命令导出的时候使用的客…...
Tomcat优化指南
以下是一份详细的Tomcat优化指南: 一、JVM(Java虚拟机)优化 内存设置 堆内存(Heap Memory) 调整-Xms(初始堆大小)和-Xmx(最大堆大小)参数。一般来说,将初始…...
本地调试自定义Maven Plugin步骤
添加自定义插件到dependencies 找到对应依赖的类,打上断点。 debug运行插件。...
css实现文字描边
效果 学习啦 -webkit-text-stroke-width: 设置文本描边的宽度,值可以是任何长度单位(如 px, em, rem 等) -webkit-text-stroke-color:设置文本描边的颜色,值可以是任何颜色值(如 red, green, bl…...
B2B营销的新篇章:开源AI智能名片S2B2C商城小程序的应用探索
摘要: B2B营销,作为企业间营销活动的总称,因其独特的业务特性而呈现出不同于B2C营销的显著特征。在数字化转型的大潮中,B2B企业正积极探索新的营销手段以提高效率和竞争力。本文旨在探讨B2B营销的基本特性,并重点引入…...
坐标系统转换方法研究与实现
坐标系统转换方法研究与实现 摘要:坐标系统是测量工作中定位的基础,坐标系统有很多形式和基准,不同历史时期所建立和使用的坐标系是不同的。随着科学技术的进步,测量方法和观测技术不断改进,采用的参考椭球及定位方式也逐步完善和精化。为更加精确的确定点位信息并综合利…...
naive ui 使用地址记录
naive ui 地址Naive UI Naive UI 是一个 Vue3 的组件库。 要了解如何安装,参见安装。 它比较完整,主题可调,用 TypeScript 写的,快...
std__invoke 的使用
std__invoke 的使用 文章目录 std__invoke 的使用1. std::invoke 的功能2. 语法3. 使用场景1. 调用普通函数2. 调用成员函数3. 调用成员函数(通过指针或引用)4. 调用函数对象(仿函数)5. 调用 Lambda 表达式 4. std::invoke 的优势…...
【Vue】深入理解v-model指令-父子组件数据绑定
一、什么是v-model? v-model是Vue.js中的一个指令,用于在表单元素上实现数据的双向绑定。简单来说,v-model可以让我们轻松地读取和更新数据,无需手动操作DOM。 二、标签选择器组件分析 我们先来看一下子组件的代码:…...
html+css+js网页设计 美食 六角西餐厅美食3个页面
htmlcssjs网页设计 美食 六角西餐厅美食3个页面 (带js) 网页作品代码简单,可使用任意HTML辑软件(如:Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作)。 获取…...
ubuntu 常见问题(持续记录)
1 ubuntu server 22.04 设置静态 IP ubuntu server 在重启之后,IP 会变化,这很不利于作内网穿透,因此很有必要使用静态 IP。 登录进系统之后: cd /etc/netplan/ ls # 我这里是 50-cloud-init.yamlifconfig # 查看网卡接口&…...