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

【axios】的浅度分析

一、Axios的拦截器能干些什么?

Axios拦截器的实现原理主要涉及两个方面:请求拦截器和响应拦截器,它们分别在请求发送前和响应返回后进行预处理和后处理。

Axios内部维护了两个数组,一个用于存储请求拦截器,另一个用于存储响应拦截器。每个拦截器都是一个函数,这些函数按照它们在数组中定义的顺序被依次执行。

1、请求拦截器:

当Axios发起一个请求时,会首先遍历并执行请求拦截器数组中的每个函数。
请求拦截器的作用是在请求发送前对请求进行修改或添加一些公共的逻辑,例如给每个请求体都加上token,或者修改请求的配置,如headers、url、params等。此外,也可以在此阶段取消请求。
请求拦截器的修改或添加的配置将被用于之后的请求发送。

2、响应拦截器:

一旦请求被发送并得到响应,Axios会遍历并执行响应拦截器数组中的每个函数。
响应拦截器的作用是在响应返回后对响应进行特定的处理,例如对返回的数据进行统一处理或对特定的错误进行处理。
如果响应是一个正常的响应,可以直接返回数据或对数据进行修改。如果响应是一个错误(例如,404或500状态码),可以进行错误处理或重试逻辑。

使用Axios拦截器的好处包括统一处理公共逻辑,减少重复代码,提高代码的可读性和可维护性。同时,也可以在请求或响应不符合预期时进行统一处理,提高程序的健壮性。

需要注意的是,在使用Axios拦截器时,应确保请求拦截器在响应拦截器之前执行,避免逻辑上的错误。此外,应避免在拦截器中修改原始请求或响应数据,以免影响其他拦截器或请求处理器的处理结果。同时,应考虑性能问题,避免在拦截器中进行耗时的操作。

综上所述,Axios拦截器的实现原理主要基于其内部维护的请求和响应拦截器数组,通过依次执行这些拦截器函数,实现对请求和响应的预处理和后处理。

二、Axios 源码中,拦截器是怎么实现的?(最简化的理解)

Axios 的拦截器实现基于 Axios 的核心原理,即 Axios 实例是一个包含请求和响应拦截器堆栈的对象。当发出请求或接收响应时,Axios 会遍历这些拦截器,并按照添加的顺序执行请求拦截器,以及按照相反的顺序执行响应拦截器。
在 Axios 的源码中,拦截器是通过一个 AxiosInterceptorManager 实例来管理的,它维护了一个拦截器数组。每个拦截器都是一个包含 fulfilledrejected 函数的对象。这两个函数分别对应于拦截器成功处理和拦截器处理出错的情况。
以下是 Axios 拦截器管理器的一个简化版本,展示了其核心实现思路:

class InterceptorManager {constructor() {this.handlers = []; // 存储拦截器的数组}use(fulfilled, rejected) {this.handlers.push({fulfilled: fulfilled,rejected: rejected});return this.handlers.length - 1; // 返回拦截器的ID}eject(id) {if (this.handlers[id]) {this.handlers[id] = null; // 移除拦截器}}forEach(fn) {this.handlers.forEach((h) => {if (h !== null) {fn(h);}});}
}

在发送请求或接收响应时,Axios 会创建一个 promise 链,并通过 forEach 方法将拦截器中的 fulfilledrejected 函数添加到这个链中。这样,每个拦截器都可以对请求或响应进行处理,然后将结果传递到链的下一个拦截器,或者在出错时结束链的执行。
PS:注意,上面说的是拦截管理器,并非下面要说的拦截器

axios.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {chain.unshift(interceptor.fulfilled, interceptor.rejected);
});axios.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {chain.push(interceptor.fulfilled, interceptor.rejected);
});

在 Axios 的完整实现中,这个拦截器机制被集成到了 Axios 的请求发送和响应处理流程中。通过这种方式,Axios 可以在发送请求之前和接收响应之后,但在用户定义的 .then.catch 执行之前,插入自定义的逻辑。
请注意,这里提供的代码只是为了说明 Axios 拦截器的实现原理,并不是 Axios 源码的完整复制。

三、高度简化的源码(axios拦截器实现源码)

Axios 拦截器的实现源码涉及到其核心模块的设计。Axios 允许你注册请求拦截器和响应拦截器,这些拦截器在请求发送前和响应返回后进行相应的处理。以下是简化的 Axios 拦截器实现源码的概述:

// 假设 Axios 实例有一个 interceptors 对象,其中包含了 request 和 response 两个数组
const instance = {interceptors: {request: [],response: []}
};// 请求拦截器的函数定义
function onFulfilled(fulfilled, rejected) {return function (config) {return new Promise((resolve, reject) => {try {const result = fulfilled(config);if (result && typeof result.then === 'function') {result.then(resolvedConfig => {resolve(resolvedConfig);}, rejected);} else {resolve(result);}} catch (error) {reject(error);}};};
}// 响应拦截器的函数定义
function onFulfilledResponse(fulfilled, rejected) {return function (response) {return new Promise((resolve, reject) => {try {const result = fulfilled(response);if (result && typeof result.then === 'function') {result.then(resolvedResponse => {resolve(resolvedResponse);}, rejected);} else {resolve(result);}} catch (error) {reject(error);}};};
}// 添加请求拦截器
instance.interceptors.request.use = function (fulfilled, rejected) {this.interceptors.request.push({fulfilled: onFulfilled(fulfilled, rejected),rejected: rejected});return this;
};// 添加响应拦截器
instance.interceptors.response.use = function (fulfilled, rejected) {this.interceptors.response.push({fulfilled: onFulfilledResponse(fulfilled, rejected),rejected: rejected});return this;
};// 简化版的请求发送函数,用于展示拦截器如何处理
function dispatchRequest(config) {return new Promise((resolve, reject) => {// 遍历并执行请求拦截器const chain = [Promise.resolve(config)];instance.interceptors.request.forEach(interceptor => {chain.unshift(interceptor.fulfilled, interceptor.rejected);});// 遍历并执行响应拦截器chain.push(dispatchRequestToServer); // 假设这个函数是实际发送请求到服务器的函数while (chain.length) {const currentInterceptor = chain.shift();const nextInterceptor = chain.shift();if (typeof currentInterceptor === 'function') {currentInterceptor(config).then(chain => {if (typeof nextInterceptor === 'function') {nextInterceptor(chain);} else {resolve(chain);}}).catch(reject);}}});
}// 假设函数,用于实际发送请求到服务器
function dispatchRequestToServer(config) {// 这里应该是实际的请求发送逻辑,为了简化,我们直接返回一个模拟的响应return Promise.resolve({data: 'Response data'});
}// 使用拦截器
instance.interceptors.request.use(config => {// 在发送请求之前做些什么console.log('Request interceptor called', config);// 可以在这里修改config对象return config;},error => {// 对请求错误做些什么return Promise.reject(error);}
);instance.interceptors.response.use(response => {// 对响应数据做点什么console.log('Response interceptor called', response);// 可以在这里修改响应数据return response;},error => {// 对响应错误做点什么return Promise.reject(error);}
);// 发送请求
dispatchRequest({ url: 'https://api.example.com/data' }).then(response => {console.log('Response received:', response);}).catch(error => {console.error('Error occurred:', error);});

以上代码是一个高度简化的版本,用于展示 Axios 拦截器是如何实现的。如果你对 Axios 的拦截器实现细节感兴趣,建议查看 Axios 的官方 GitHub 仓库中的源码。

相关文章:

【axios】的浅度分析

一、Axios的拦截器能干些什么? Axios拦截器的实现原理主要涉及两个方面:请求拦截器和响应拦截器,它们分别在请求发送前和响应返回后进行预处理和后处理。 Axios内部维护了两个数组,一个用于存储请求拦截器,另一个用于…...

基于单片机的步进电机控制系统研究

摘 要 : 近年来 , 步进电机凭借其定位精度高 、 使用方便 、 性价比高 、 容易控制等优点 , 在各领域受到广泛应用 。 文中利用C52 单片机设计了一种步进电机控制系统 , 介绍了其总体方案 、 主控制模块 、 驱动电路 、 键盘 、 晶…...

Fine-tuning和模型训练的关系

概述 Fine-tuning和模型训练不是完全相同的概念,但它们之间有密切的关系,都是机器学习和深度学习过程中的重要步骤。 模型训练是一个更广泛的概念,指的是使用数据去调整模型的内部参数,以使得模型能够从输入数据中学习并做出预测…...

【ai】livekit:Agents 3 : pythonsdk和livekit-agent的可编辑模式下的安装

livekit-agent 依赖于livekit、livekit-api、livekit-protocol 其中livekit就是livekkit-rtc: 包含俩sdk 实时互动sdkReal-time SDK for connecting to LiveKit as a participant livekit-api : 服务端sdk https://pypi.org/project/livekit-api/ livekit的python sdk...

【传知代码】BERT论文解读及情感分类实战-论文复现

文章目录 概述原理介绍BERT模型架构任务1 Masked LM(MLM)任务2 Next Sentence Prediction (NSP)模型输入下游任务微调GLUE数据集SQuAD v1.1 和 v2.0NER 情感分类实战IMDB影评情感数据集数据集构建模型构建 核心代码超参数设置训练结果注意事项 小结 本文…...

【C language】判断一个正整数是否是2^n

题解:判断一个正整数是否是2^n(位运算方法) 1.题目 判断一个正整数是否是2^n 2.位运算法 思路:干掉二进制最右边的1,看是否是0 int main() {int num 16;if ((num & (num - 1)) 0) printf("the num is a 2^n");else print…...

解锁Android高效数据传输的秘钥 - Parcelable剖析

作为Android开发者,我们经常需要在不同的组件(Activity、Service等)之间传输数据。这里的"传输"往往不仅仅是简单的数据复制,还可能涉及跨进程的内存复制操作。当传输的数据量较大时,这种操作可能会带来严重的性能问题。而Android系…...

前端 CSS 经典:filter 滤镜

前言:什么叫滤镜呢,就是把元素里的像素点通过一套算法转换成新的像素点,这就叫滤镜。而算法有 drop-shadow、blur、contrast、grayscale、hue-rotate 等。我们可以通过这些算法实现一些常见的 css 样式。 1. drop-shadow 图片阴影 可以用来…...

专业的力量-在成为专家的道路上前进

专业的力量-在成为专家的道路上前进 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 现在稀缺的已不再是信息资源,而是运用信息的能力。过去…...

10分钟掌握FL Studio21中文版,音乐制作更高效!

FL Studio 21中文版是Image Line公司推出的一款深受欢迎的数字音频工作站软件,在音乐制作领域享有盛誉。这个版本特别针对中文用户进行了本地化处理,旨在提供更加便捷的用户体验和操作界面。本次评测将深入探讨FL Studio 21中文版的功能特点、使用体验及…...

Python中4种读取JSON文件和提取JSON文件内容的方法

在Python中,有几种常用的方法可以用于读取JSON文件并提取数据。以下是四种主要的方法 使用iamn 1oad:0”:这个方法用于格一个包合S0N文档的字符串(enr、wtas典otea实列)反席列化 (0eseia28)为Pm0n%象。例如,如果你有一个ISON格式的字荷电,你…...

el-pagination在删除非第一页的最后一条数据遇到的问题

文章目录 前言一、问题展示二、解决方案三、源码解析1、elementui2、elementplus 总结 前言 这个问题是element-ui中的问题,可以从源码中看出来,虽然页码更新了,active也是对的,但是未调用current-change的方法,这里就…...

视频汇聚平台LntonCVS视频监控系统前端错误日志记录及Debug模式详细讲解

LntonCVS作为一种支持GB28181标准的流媒体服务平台,旨在提供一个能够整合不同厂商设备、便于管理和扩展的解决方案,以适应日益复杂的视频监控环境。通过实现设备的统一管理和流媒体的高效传输,LntonCVS帮助构建更加灵活和强大的视频监控系统。…...

高并发项目-用户登录基本功能

文章目录 1.数据库表设计1.IDEA连接数据库2.修改application.yml中数据库的名称为seckill3.IDEA创建数据库seckill4.创建数据表 seckill_user5.密码加密分析1.传统方式(不安全)2.改进方式(两次加密加盐) 2.密码加密功能实现1.pom.…...

kotlin基础之泛型和委托

Kotlin泛型的概念及使用 泛型概念 在Kotlin中,泛型(Generics)是一种允许在类、接口和方法中使用类型参数的技术。这些类型参数在实例化类、实现接口或调用方法时会被具体的类型所替代。泛型的主要目的是提高代码的复用性、类型安全性和可读…...

awtk踩坑记录二:移植jerryscript到awtk design项目

工作要求,想尝试看看在awtk-designer设计界面的同时能不能用javascript开发逻辑层,以此和前端技术联动,本文是一种项目建构的思路。 从github下载并编译awtk, awtk-mmvm和awtk-jerryscript(如果没有) 用awtk-designer…...

正邦科技(day2)

自动校准 问题:电量不准都可以直接去校准 校准方式:可程式变频电压 问题分析:他是通过软件去自动自动校准的,flash 清空的时候有缓存没有清空,或者互感器没有读取到问题 互感器:电流互感器的作用包括电流测…...

技术架构设计指南:从需求到实现

技术架构是软件系统的骨架,它决定了系统的性能、可靠性、扩展性等关键特性。本文将介绍技术架构设计的一般步骤和方法。 第一步:需求分析 在设计技术架构之前,首先要对系统需求进行全面深入的分析。这包括功能需求、非功能需求(如…...

【数据结构:排序算法】堆排序(图文详解)

🎁个人主页:我们的五年 🔍系列专栏:数据结构课程学习 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 🍩1.大堆和小堆 🍩2.向上调整算法建堆和向下调整算法建堆:…...

git 派生仓库怎么同步主仓库的新分支

一、git 派生仓库怎么同步主仓库的新分支 要使你的Git派生仓库同步主仓库的新分支,请遵循以下步骤: 1、添加上游仓库(如果尚未添加): 如之前所述,确保上游仓库已经被添加到你的本地仓库。如果没有,使用命…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...