axios原理深入源码解析

【算力网络】算力知识 尽管算力这个词在近年来很“火”,但其背后的含义,却很少有人真正了解 阅读详情

axios


axios的github地址上明确写了axios的特征是
Make XMLHttpRequests from the browser(从浏览器发起XMLHttpRequests请求)
Make http requests from node.js(从node.js发起http请求)
Supports the Promise API(支持PromiseAPI)
Intercept request and response(拦截请求和响应)
Transform request and response data(转换请求和响应数据)
Cancel requests(取消请求)
Automatic transforms for JSON data(自动转换json数据)
Client side support for protecting against XSRF(客户端支持自动防止XSRF)
下面就这些特征查看源码来解析

可以在浏览器和服务器上发起请求

上面已经写了,axios可以在浏览器发起XMLHttpRequests请求,而在node.js可以发起http请求,也即是说,axios可以在浏览器和服务器上都可以发起请求
看看axios的源码目录
在这里插入图片描述
其中xhr.js是浏览器上发起请求,http.js是服务器上发起请求
我们能看到,xhr.js中有一行代码

var request = new XMLHttpRequest();

可以明确看到,在浏览器上的请求是基于XMLHttpRequest的
而http.js中的请求,可以在最后看到

if (utils.isStream(data)) {
  data.on('error', function handleStreamError(err) {
    reject(enhanceError(err, config, null, req));
  }).pipe(req);
} else {
  req.end(data);
}

通过在这段代码前对data进行处理,在这里最后发出请求

支持promise API

我们知道,promise是ES6中出现的语法,很好地处理了异步,而axios中支持promise
关于这一点,我们从axios的使用就可以看出来axios的get方法返回了一个promise,然后我们对其进行操作,其他的请求也是一样

axios.get('url')
	.then(res=>{
		// 响应处理
	}).catch(err=>{
		// 错误处理
})

在github上的源码也可以看到这部分明确返回了一个promise

Axios.prototype.request = function request(config) {
  /*eslint no-param-reassign:0*/
  // Allow for axios('example/url'[, config]) a la fetch API
  if (typeof config === 'string') {
    config = arguments[1] || {};
    config.url = arguments[0];
  } else {
    config = config || {};
  }

  config = mergeConfig(this.defaults, config);

  // Set config.method
  if (config.method) {
    config.method = config.method.toLowerCase();
  } else if (this.defaults.method) {
    config.method = this.defaults.method.toLowerCase();
  } else {
    config.method = 'get';
  }

  // Hook up interceptors middleware
  var chain = [dispatchRequest, undefined];
  var promise = Promise.resolve(config);

  this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
    chain.unshift(interceptor.fulfilled, interceptor.rejected);
  });

  this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
    chain.push(interceptor.fulfilled, interceptor.rejected);
  });

  while (chain.length) {
    promise = promise.then(chain.shift(), chain.shift());
  }

  return promise;
};

拦截请求和响应及转换数据

拦截器的相关代码也在上面promise里面的代码,我将相关的代码拿出来

// 将拦截器放在第一个,undefined放在第二个
// 在后面的处理中,是两个两个处理的
// 因为使用了promise.then,其第一个参数对应的是resolve第二个参数对应的是rejected
// 拦截器会对应于resolve,undefined会对应于rejected
var chain = [dispatchRequest, undefined];
var promise = Promise.resolve(config);
// 将请求拦截器中间件添加到chain数组头部
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
  chain.unshift(interceptor.fulfilled, interceptor.rejected);
});
// 将响应拦截器中间件添加到chain数组尾部
this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
  chain.push(interceptor.fulfilled, interceptor.rejected);
});
// 依次使用promise处理chain数组内的东西
while (chain.length) {
  // 这里使用shift方法,每次调用两次这个方法,即是每次拿出数组中的两个拦截器
  promise = promise.then(chain.shift(), chain.shift());
}

而找寻里面的dispatchRequest,会发现它是从dispatchRequest.js中import过来的

var dispatchRequest = require('./dispatchRequest');

在dispatchRequest.js中,我们可以找到拦截请求和响应的相关代码,在这里对请求和响应的数据做了转换

// 处理请求的数据
response.data = transformData(
  response.data,
  response.headers,
  config.transformResponse
);
// 处理响应的数据
var adapter = config.adapter || defaults.adapter;

return adapter(config).then(function onAdapterResolution(response) {
  throwIfCancellationRequested(config);

  // Transform response data
  response.data = transformData(
    response.data,
    response.headers,
    config.transformResponse
  );

  return response;
}, function onAdapterRejection(reason) {
  if (!isCancel(reason)) {
    throwIfCancellationRequested(config);

    // Transform response data
    if (reason && reason.response) {
      reason.response.data = transformData(
        reason.response.data,
        reason.response.headers,
        config.transformResponse
      );
    }
  }

取消请求

axios提供了取消请求的接口,实际上在源码中还是通过最关键的一步request.abort()来取消请求,使用isCancel来作为是否已经取消的标识,使用Cancel来作为重复取消时抛出的错误,使用CancelToken来作为取消请求的核心处理,在处理中采取promise异步的方法
具体的过程详见axios请求取消步骤源码详解
axios的取消请求相比于我们直接使用abort,因为在promise中写入重复触发时会抛出cancel对象,所以无需我们自己去解决按钮被连续多次点击的问题,同时取消请求也能在我们发出多个相关联请求时,使用最新的数据。

防止XSRF攻击

首先我们说说XSRF攻击是什么,简单来说,XSRF攻击就是当我们访问A页面,在拿到相应的cookie后,去访问一个不安全的B页面,而这个B页面通过script,img,video这些标签的src属性,发起了请求,而因为此时A页面的cookie还没失效,在避过同源策略的同时,向A页面所在的服务器发起一个请求,而这个请求会带上之前的cookie,于是会导致一些安全问题。

为了防止XSRF攻击,axios采用了在给请求添加一个自定义属性,传入一个token,在服务器判断该属性值是否一样
看看源码内容xhr.js

// 判断是否为标准的浏览器环境
if (utils.isStandardBrowserEnv()) {
  var cookies = require('./../helpers/cookies');

  // isURLSameOrigin判断是否有跨域,如果有跨域的话需要有凭证
  // 凭证的作用是判断当前请求为跨域类型时是否在请求中协带cookie
  // 满足上面条件后,判断是否有config.xsrfcookieName
  // 如果有的话,使用cookies的read方法处理值后赋值给xsrfValue
  var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ?
    cookies.read(config.xsrfCookieName) :
    undefined;

  if (xsrfValue) {
    requestHeaders[config.xsrfHeaderName] = xsrfValue;
  }
}

首先axios会判断当前环境是否为标准的浏览器环境,如果是标准的浏览器环境的话,就会继续执行。对于XSRF攻击来说,最基本的就是跨域了,所以我们对发出请求的域和当前的域做同源判断,如果是跨域的话,就必须有凭证config.withCredentials || isURLSameOrigin(fullPath),凭证简单来说就是当前请求在跨域时是否可以带上cookie。
在满足上面条件时,即是同源或者跨域但是有凭证这两种情况,同源的我们自然不必再处理,而对于跨域的我们接下去看,当config中有xsrfCookieName时,将config.xsrfCookieName的内容使用cookies.read处理后返回给xsrfValue
cookies.read在cookies.js中

read: function read(name) {
  var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
  return (match ? decodeURIComponent(match[3]) : null);
},

最后,当xsrfValue存在时将其加入请求头中,这里的config.xsrfHeaderName就是自定义的属性,在defaults.js中可见

xsrfHeaderName: 'X-XSRF-TOKEN',

缺点


  1. 不支持jsonp,需要自己封装
  2. 基于XMLHttpRequest实现,所以无法在service worker,web worker中使用

(有待补充)

解决【x2openEuler环境检查未通过——CheckRepoCurlActor不通过】问题 摘要:x2openEuler使用默认repo源时出现环境检查失败问题,原因是默认源返回308永久重定向错误。解决方法包括:1)为CentOS主机配置华为yum源;2)在x2openEuler Web界面修改为自定义可用源。具体步骤包括备份原源、下载华为源、清除缓存,并通过curl测试确认新源可用性。最终成功配置openEuler-24.03-LTS-SP1版本的repo源后,环境检查顺利通过。 阅读详情

相关推荐

Ansys Zemax与Speos协同设计:HUD系统从光学优化到驾驶模拟的全流程解析

本文详细解析了如何利用Ansys Zemax与Speos这对“黄金搭档”进行HUD系统的协同设计。流程始于Zemax进行核心光学架构与像差优化,奠定性能基础;随后将设计无缝导入Speos,通过HUD光学分析模块进行量化验证;最终在虚拟驾驶环境中进行沉浸式模拟,评估实际视觉体验与系统集成效果,实现从光学优化到驾驶模拟的全流程闭环。

weixin_29201933的博客 273

axios是如何实现的(源码解析)

该文件创建了一个axios实例,并且导出,所以我们import axios from 'axios'引入的就是该实例,可以直接使用,不需要再new Axios({...})这样写。从上面的文件可以看出,axios扩展了Axios的原型方法和Axios实例的属性,所以接下来要重点看Axios的类里有什么内容。在阅读源码之前,先大概了解一下axios实例的属性和请求整体流程,带着这些概念,阅读源码可以轻松不少!下图是axios的请求流程,其实相当简单,先了解这个流程,看源码的时候就会有方向。

weixin_66128399的博客 1363

从ADS到SystemVue:当简单链路预算不够用时,我的射频系统级仿真方案升级实录

本文详细介绍了从ADS到SystemVue的射频系统级仿真升级路径,重点分析了基础链路预算在多端口元件和复杂场景下的局限性,并提供了SystemVue在非线性系统验证和跨域协同分析中的优势。通过实际案例展示了如何平滑迁移工具链,提升仿真精度和效率,适用于5G、毫米波雷达等现代射频系统设计。

weixin_34233974的博客 343

axios的原理以及源码讲解

手写实现一个axios 以及axios的原理

努力的鋜 554

电力现货市场出清机制与节点电价计算实战解析

本文深入解析了电力现货市场的出清机制,特别是节点边际电价的计算原理与实战应用。通过一个基于Matlab和IEEE30节点系统的完整案例,详细演示了如何利用最优潮流模型求解市场出清价格,并提取节点电价,揭示了电网阻塞如何影响实时电价的形成。

weixin_29061425的博客 950

高通开发系列 - Bootloader之lk匹配dtb和dtbo中msm-id和board-id的知识

lk匹配dtb和dtbo中的msm-id和board-id等知识

fulinux的博客 4245

[css] 在固定宽度的div下,怎么让字体自适应大小,不超出宽度,也不要换行

[css] 在固定宽度的div下,怎么让字体自适应大小,不超出宽度,也不要换行 .item-codes{width:800px;word-break: break-all;white-space: normal;} 个人简介 我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易, 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题 ...

歌谣的博客 3709

政务帮办新范式:基于检索增强与多智能体协同的智能系统实践

本文提出了一种多智能体协同的智能政务系统架构,突破传统方案在状态管理、职责过载和感知闭环方面的局限。系统由中央规划智能体、对话引导智能体、参数提取智能体和执行状态分析智能体组成,通过职责分离与显式状态管理实现高效协同。核心创新在于中央决策引擎的确定性逻辑,采用基于规则的状态机设计,确保系统可靠可控。该架构支持自然语言交互、参数自动提取、业务系统操作和视觉闭环验证,能够真正实现"帮办"功能,显著提升政务服务的智能化水平。

469

axios的原理及源码解析

axios解析

weixin_50367873的博客 1495

46.qt quick-自定义非常好看的qml虚拟软键盘-支持换肤、动态加载移除语言(二)

在上章我们学习了45.qt quick-qml虚拟软键盘详解(一)_诺谦的博客-优快云博客 接下来我们便来自定义一款好看的qml软键盘.如下图所示: 支持背景更换、支持动图: 支持动态加载移除语言: 支持拖拽、自由缩小放大: 支持定位坐标: ...

抵抗时间扭曲,坚持做一件有意义的事 4674

【异常】OpenClaw 项目 `fetch failed` 报错问题排查与解决方案Response interrupted: TypeError: fetch failed

针对无超时控制、异常兜底缺失导致的请求中断,封装标准化的安全请求工具,一次性解决超时控制、异常捕获、日志埋点三大问题,全项目替换原生。:将项目运行的 Node.js 版本升级至 18.x 及以上 LTS 版本,使用 Node.js 内置的稳定版。实现的网络请求环节,包括但不限于:第三方开放接口调用、内部服务接口通信、跨域资源请求、外部配置拉取等场景。:针对无法升级 Node.js 版本的存量环境,通过社区稳定兼容包替换原生。类型异常,直接造成业务请求响应中断。第二步:业务代码改造,替换原生。

奶爸的编程之路,也就一周冷个三天 367

OkHttp全解析(二)——源码解析

目录源码解析构建OkHttpClient请求工厂创建Request实例配置请求参数newCall开始执行网络请求同步请求 源码解析 OkHttp的使用步骤 创建OkHttpClient实例 创建Request 实例并配置请求参数 通过OkHttpClient对象的newCall方法得到Call对象 调用call对象的execute或者enqueue执行网络请求 处理请求返回的数据 构建OkHttpClient请求工厂 OkHttpClient是用于请求的工厂,可用于发送HTTP请求并读取其响应。创建一个

whale的博客 681

PCIE2.0/PCIE3.0/PCIE4.0/PCIE5.0接口的带宽、速率计算

一、PCIE接口速率: 二、PCIE相关概念: 传输速率为每秒传输量GT/s,而不是每秒位数Gbps,因为传输量包括不提供额外吞吐量的开销位; 比如 PCIe 1.x和PCIe 2.x使用8b / 10b编码方案,导致占用了20% (= 2/10)的原始信道带宽。 GT/s —— Giga transation per second (千兆传输/秒),即每一秒内传输的次数。重点在于描述物理层通信协议的速率属性,可以不和链路宽度等关联。 Gbps —— Giga Bits Per Second

技术联盟 1万+

axios超详细源码解析及实现原理

axios超详细源码解析及实现原理

qq_42880714的博客 1万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

深入解析axios原理及源码探究

axios是一个基于Promise的HTTP客户端,用于浏览器和node.js。它具有丰富的配置选项、拦截器机制和取消请求的功能,非常适合在复杂的前端应用中使用。在上一篇文章中,我们简要介绍了axios的基本使用方法。类实现,允许用户通过调用取消方法来取消正在进行的请求。中,主要包括创建实例、拦截器处理、请求方法的挂载等。类管理,可以在请求前和响应后添加自定义逻辑。axios的核心实现在。

全栈若城,专注知识分享 3万+

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

一步一步解析Axios源码,从入门到原理

一. Axios是什么?一个基于 Promise来管理http 请求的简洁、易用且高效的代码封装库。通俗一点来讲,它是一个前端替代Ajax的一个东西,可以使用它发起...

全栈者 的博客 5705

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

安装axios_一步一步解析Axios源码,从入门到原理

一. Axios是什么?一个基于 Promise来管理http 请求的简洁、易用且高效的代码封装库。通俗一点来讲,它是一个前端替代Ajax的一个东西,可以使用它发起http请求接口功能,它是基于Promise的,相比于Ajax的回调函数能够更好的管理异步操作。二. Axios的特点三. 安装Axios1、通过使用npm命令安装它。npm i axios --save2、 安装成功...

weixin_39801165的博客 271

axios不发起请求_一步一步解析Axios源码,从入门到原理

一. Axios是什么?一个基于 Promise来管理http 请求的简洁、易用且高效的代码封装库。通俗一点来讲,它是一个前端替代Ajax的一个东西,可以使用它发起http请求接口功能,它是基于Promise的,相比于Ajax的回调函数能够更好的管理异步操作。二. Axios的特点三. 安装Axios1、通过使用npm命令安装它。npm i axios --save2、 安装成功...

weixin_36202603的博客 358

axios参数传递的底层原理:从源码解析data和params的差异

本文深入解析axios中data和params参数传递的底层原理,通过源码分析揭示两者在HTTP请求中的位置、编码方式及适用场景的差异。data参数用于POST请求体,支持JSON序列化;params参数转为URL查询字符串,适合GET请求。掌握这些区别能有效提升前后端联调效率。

weixin_30879169的博客 438

axios-retry源码解析:深入理解拦截器与重试机制实现原理

axios-retry是一个功能强大的Axios插件,它能够拦截失败的请求并在可能的情况下自动重试,有效提升网络请求的稳定性和可靠性。本文将深入剖析axios-retry的源码实现,帮助开发者理解其拦截器工作原理和重试机制设计。 ## 核心功能与项目结构 axios-retry作为Axios生态中的重要补充,通过拦截器机制实现了请求失败后的智能重试。项目采用TypeScript开发,主要代码集

gitblog_00047的博客 537

axios-cache-interceptor 源码解析:深入理解拦截器实现原理和缓存机制

axios-cache-interceptor 是一个为 axios 设计的轻量级高效缓存拦截器,支持 Etag、Cache-Control、TTL、HTTP 头等多种缓存策略。它能帮助开发者轻松实现请求缓存功能,提升应用性能和用户体验。 ## 项目概述 axios-cache-interceptor 作为一款强大的 axios 缓存拦截器,以其高性能、小巧体积和丰富功能而受到开发者青睐。它的

gitblog_01090的博客 345

Axios 源码解读 —— request 篇

Axios 是一个基于 promise 网络请求库,作用于 node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和 node.js 中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。 从 Axios 的官方介绍可以得知,这是一个可以同时运行在浏览器客户端 + Node 服务端的网络请求库,在浏览器运行时,使用 XMLHttpRequests 构建请求,在 Node 环境时使用 node 的 htt

qq_34621851的博客 7272

axios源码解析-Axios对象

axios源码解析-Axios对象 之前说过,axios中,axios本身是一个函数,但它绑定了Axios构造函数的所有方法,那么,Axios这个构造函数究竟有那些属性和方法呢,在axios的源码中,有专门的一个文件Axios.js去编写这个构造函数,那么我们先来看一下源码中是如何写的 // 检验版本的对象 var validators = validator.validators; /** * Create a new instance of Axios * * @param {Object} in

qq_54684701的博客 521

axios从入门到源码分析之axios 源码分析(二)

1. 从语法上来说: axios 不是 Axios 的实例;2. 从功能上来说: axios 是 Axios 的实例;3. axios 是 Axios.prototype.request 函数 bind()返回的函数;4. axios 作为对象有 Axios 原型对象上的所有方法, 有 Axios 对象上所有属性;...

总结前端开发中遇到的问题,分享前端知识 309

【笔记】 axios - api、源码、源码模仿

axios

LawssssCat的博客 766

axios 源码分析的总结

一、axios 源码分析的总结 axios 与 Axios 的关系,如下所示: 从语法上来说: axios 不是 Axios 的实例 从功能上来说: axios是 Axios 的实例 axios 是 Axios.prototype.request 函数 bind() 返回的函数 axios 作为对象有 Axios 原型对象上的所有方法, 有 Axios 对象上所有属性 instance与 axios 的相同点,如下所示: 都是一个能发任意请求的函数: request(config) 都有发特定

浮生离梦的博客 227
上一篇: axios请求取消步骤源码详解
下一篇: 详解JavaScript异步执行顺序
前端小黑
博客等级 码龄9年 148粉丝 222原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值