axios源码分析之请求adapter

axios源码分析之请求adapter

axios changeLog

注:axios从 v1.7.0-beta.0 支持了fetch

v1.7.0-beta.0 changgeLog

Featuresadapter: add fetch adapter; (#6371) (a3ff99b)Contributors to this releaseavatar Dmitriy Mozgovoyavatar Jay

v1.7.0-beta.0 之前的版本

以 v0.27.2版本为例 是如何使用 Adapter

当处理请求时会使用 dispatchRequest方法,该方法出现了adapter方法,adapter方法中传入了config(即构造axios请求时传入的请求配置,包含headers,请求参数等),

  • 当成功时会返回 response
  • 当失败时会返回 Promise.reject(reason)

【注】axios\lib\core\dispatchRequest.js

  /// ....codevar defaults = require('../defaults');///...code var adapter = config.adapter || defaults.adapter;return adapter(config).then(function onAdapterResolution(response) {throwIfCancellationRequested(config);// Transform response dataresponse.data = transformData.call(config,response.data,response.headers,config.transformResponse);return response;}, function onAdapterRejection(reason) {if (!isCancel(reason)) {throwIfCancellationRequested(config);// Transform response dataif (reason && reason.response) {reason.response.data = transformData.call(config,reason.response.data,reason.response.headers,config.transformResponse);}}return Promise.reject(reason);});

来看看defaults.adapter 到底是什么黑魔法?

【注】一般我们在构造axios 请求时不会自己传入adapter,所以此处不会去关注 config.adapter

var adapter = config.adapter || defaults.adapter;

从dispatchRequest.js 源码中我们可以看到 defaults 来源于 axios\lib\defaults\index.js 文件, 该文件导出了defaults对象,defaults.adapter 来源于getDefaultAdapter 返回的值,

getDefaultAdapter 方法

  • 先判断 XMLHttpRequest 是否存在,存在就使用 xhr 请求
  • 判断process 是否为 undefined 判断是否为node 环境,然后就用 http 包发起起请求
function getDefaultAdapter() {var adapter;if (typeof XMLHttpRequest !== 'undefined') {// For browsers use XHR adapteradapter = require('../adapters/xhr');} else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {// For node use HTTP adapteradapter = require('../adapters/http');}return adapter;
}

【注】axios\lib\defaults\index.js

'use strict';var utils = require('../utils');
var normalizeHeaderName = require('../helpers/normalizeHeaderName');
var AxiosError = require('../core/AxiosError');
var transitionalDefaults = require('./transitional');
var toFormData = require('../helpers/toFormData');var DEFAULT_CONTENT_TYPE = {'Content-Type': 'application/x-www-form-urlencoded'
};function setContentTypeIfUnset(headers, value) {if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {headers['Content-Type'] = value;}
}function getDefaultAdapter() {var adapter;if (typeof XMLHttpRequest !== 'undefined') {// For browsers use XHR adapteradapter = require('../adapters/xhr');} else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {// For node use HTTP adapteradapter = require('../adapters/http');}return adapter;
}function stringifySafely(rawValue, parser, encoder) {if (utils.isString(rawValue)) {try {(parser || JSON.parse)(rawValue);return utils.trim(rawValue);} catch (e) {if (e.name !== 'SyntaxError') {throw e;}}}return (encoder || JSON.stringify)(rawValue);
}var defaults = {transitional: transitionalDefaults,adapter: getDefaultAdapter(),transformRequest: [function transformRequest(data, headers) {normalizeHeaderName(headers, 'Accept');normalizeHeaderName(headers, 'Content-Type');if (utils.isFormData(data) ||utils.isArrayBuffer(data) ||utils.isBuffer(data) ||utils.isStream(data) ||utils.isFile(data) ||utils.isBlob(data)) {return data;}if (utils.isArrayBufferView(data)) {return data.buffer;}if (utils.isURLSearchParams(data)) {setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');return data.toString();}var isObjectPayload = utils.isObject(data);var contentType = headers && headers['Content-Type'];var isFileList;if ((isFileList = utils.isFileList(data)) || (isObjectPayload && contentType === 'multipart/form-data')) {var _FormData = this.env && this.env.FormData;return toFormData(isFileList ? {'files[]': data} : data, _FormData && new _FormData());} else if (isObjectPayload || contentType === 'application/json') {setContentTypeIfUnset(headers, 'application/json');return stringifySafely(data);}return data;}],transformResponse: [function transformResponse(data) {var transitional = this.transitional || defaults.transitional;var silentJSONParsing = transitional && transitional.silentJSONParsing;var forcedJSONParsing = transitional && transitional.forcedJSONParsing;var strictJSONParsing = !silentJSONParsing && this.responseType === 'json';if (strictJSONParsing || (forcedJSONParsing && utils.isString(data) && data.length)) {try {return JSON.parse(data);} catch (e) {if (strictJSONParsing) {if (e.name === 'SyntaxError') {throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);}throw e;}}}return data;}],/*** A timeout in milliseconds to abort a request. If set to 0 (default) a* timeout is not created.*/timeout: 0,xsrfCookieName: 'XSRF-TOKEN',xsrfHeaderName: 'X-XSRF-TOKEN',maxContentLength: -1,maxBodyLength: -1,env: {FormData: require('./env/FormData')},validateStatus: function validateStatus(status) {return status >= 200 && status < 300;},headers: {common: {'Accept': 'application/json, text/plain, */*'}}
};utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {defaults.headers[method] = {};
});utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
});module.exports = defaults;

v1.7.0-beta.0 之后版本

主要增加fetch 请求方式

adapters文件夹下增加 axios\lib\adapters\adapters.js 文件
重写了 getAdapter 方法

【注】axios\lib\adapters\adapters.js

import utils from '../utils.js';
import httpAdapter from './http.js';
import xhrAdapter from './xhr.js';
import fetchAdapter from './fetch.js';
import AxiosError from "../core/AxiosError.js";const knownAdapters = {http: httpAdapter,xhr: xhrAdapter,fetch: fetchAdapter
}utils.forEach(knownAdapters, (fn, value) => {if (fn) {try {Object.defineProperty(fn, 'name', {value});} catch (e) {// eslint-disable-next-line no-empty}Object.defineProperty(fn, 'adapterName', {value});}
});const renderReason = (reason) => `- ${reason}`;const isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;export default {getAdapter: (adapters) => {adapters = utils.isArray(adapters) ? adapters : [adapters];const {length} = adapters;let nameOrAdapter;let adapter;const rejectedReasons = {};for (let i = 0; i < length; i++) {nameOrAdapter = adapters[i];let id;adapter = nameOrAdapter;if (!isResolvedHandle(nameOrAdapter)) {adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];if (adapter === undefined) {throw new AxiosError(`Unknown adapter '${id}'`);}}if (adapter) {break;}rejectedReasons[id || '#' + i] = adapter;}if (!adapter) {const reasons = Object.entries(rejectedReasons).map(([id, state]) => `adapter ${id} ` +(state === false ? 'is not supported by the environment' : 'is not available in the build'));let s = length ?(reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0])) :'as no adapter specified';throw new AxiosError(`There is no suitable adapter to dispatch the request ` + s,'ERR_NOT_SUPPORT');}return adapter;},adapters: knownAdapters
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/461626.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Cloud Sleuth(Micrometer Tracing +Zipkin)

分布式链路追踪 分布式链路追踪技术要解决的问题&#xff0c;分布式链路追踪&#xff08;Distributed Tracing&#xff09;&#xff0c;就是将一次分布式请求还原成调用链路&#xff0c;进行日志记录&#xff0c;性能监控并将一次分布式请求的调用情况集中展示。比如各个服务节…

Vision - 开源视觉分割算法框架 Grounded SAM2 配置与推理 教程 (1)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/143388189 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 Ground…

百度如何打造AI原生研发新范式?

&#x1f449;点击即可下载《百度AI原生研发新范式实践》资料 2024年10月23-25日&#xff0c;2024 NJSD技术盛典暨第十届NJSD软件开发者大会、第八届IAS互联网架构大会在南京召开。本届大会邀请了工业界和学术界的专家&#xff0c;优秀的工程师和产品经理&#xff0c;以及其它行…

初认识构建工具

初认识构建工具Webpack & Vite 目录 前言webpack 使用步骤配置文件 _entry_output✨_loader_babel_plugin_source map 开发服务器 前言 不同于node中编写代码&#xff0c;在html、css、js中不能放心使用模块化规范&#xff0c;主要是浏览器兼容性问题&#xff0c;以及…

数据结构 ——— 向上调整建堆和向下调整建堆的区别

目录 前言 向下调整算法&#xff08;默认小堆&#xff09; 利用向下调整算法对数组建堆 向上调整建堆和向下调整建堆的区别​编辑 向下调整建堆的时间复杂度&#xff1a; 向上调整建堆的时间复杂度&#xff1a; 结论 前言 在上一章讲解到了利用向上调整算法对数组进行…

分享几款开源好用的图片在线编辑,适合做快速应用嵌入

图片生成器是指一种工具或软件&#xff0c;用于自动生成图片或图像内容&#xff0c;通常依据用户设定的参数或模板进行操作。这种工具能够帮助用户快速创建视觉效果丰富的图像&#xff0c;而无需具备专业的设计技能。 在数字化时代&#xff0c;图片编辑已经成为日常工作和生活的…

我为何要用wordpress搭建一个自己的独立博客

我在csdn有一个博客&#xff0c;这个博客是之前学习编程时建立的。 博客有哪些好处呢&#xff1f; 1&#xff0c;可以写自己的遇到的问题和如何解决的步骤 2&#xff0c;心得体会&#xff0c;经验&#xff0c;和踩坑 3&#xff0c;可以转载别人的好的技术知识 4&#xff0c;宝贵…

ts:使用fs内置模块简单读写文件

ts&#xff1a;使用fs内置模块简单读写文件 一、主要内容说明二、例子&#xff08;一&#xff09;、fs模块的文件读写1.源码1 &#xff08;fs模块的文件读写&#xff09;2.源码1运行效果 三、结语四、定位日期 一、主要内容说明 在ts中&#xff0c;我们可以使用内置的fs模块来…

十个常见的软件测试面试题,拿走不谢

所有面试问题一般建议先总后分的方式来回答&#xff0c;这样可以让面试官感觉逻辑性很强。 1. 自我介绍 之所以让我们自我介绍&#xff0c;其实是面试官想找一些时间来看简历&#xff0c;所以自我介绍不用太长的时间&#xff0c;1-2分 钟即可。 自我介绍一般按以下方式进行介…

C++中关于 <functional> 的使用

#include <functional> 是 C 标准库中的一个头文件&#xff0c;主要用于提供与函数对象、函数指针和函数适配器相关的功能 一&#xff1a;定义方式 1. 定义和使用 std::function 和 Lambda 表达式 2&#xff1a;使用 std::bind 你可以使用 std::bind 来绑定函数参数&am…

Axios 请求超时设置无效的问题及解决方案

文章目录 Axios 请求超时设置无效的问题及解决方案1. 引言2. 理解 Axios 的超时机制2.1 Axios 超时的工作原理2.2 超时错误的处理 3. Axios 请求超时设置无效的常见原因3.1 配置错误或遗漏3.2 超时发生在建立连接之前3.3 使用了不支持的传输协议3.4 代理服务器或中间件干扰3.5 …

WPF+MVVM案例实战(十五)- 实现一个下拉式菜单(上)

文章目录 1 案例效果2、图标资源下载3、功能实现1.文件创建2、菜单原理分析3、一级菜单两种样式实现1、一级菜单无子项样式实现2、一级菜单有子项样式实现 4、总结 1 案例效果 提示 2、图标资源下载 从阿里矢量素材官网下载需要的菜单图片&#xff0c;如下所示&#xff1a; …

【环境搭建】Apache ZooKeeper 3.8.4 Stable

软件环境 Ubuntu 20.04 、OpenJDK 11 OpenJDK 11&#xff08;如果已经安装&#xff0c;可以跳过这一步&#xff09; 安装OpenJDK 11&#xff1a; $ sudo apt-get update$ sudo apt-get install -y openjdk-11-jdk 设置 JAVA_HOME 环境变量&#xff1a; $ sudo gedit ~/.bash…

后台管理系统的通用权限解决方案(九)SpringBoot整合jjwt实现登录认证鉴权

1&#xff09;创建maven工程jjwt-login-demo&#xff0c;并配置其pom.xml文件如下 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-ins…

国考报名照片无法使用照片审核工具上传失败的解决办法

国考报名过程中&#xff0c;照片审核是至关重要的一步&#xff0c;但许多考生在上传照片时遇到了难题&#xff0c;导致无法继续报名&#xff0c;从而影响抢考场位置&#xff0c;下面就介绍如何快速完成照片处理、审核和上传过审的技巧。 一、国考报名照片基本要求首先&#xff…

vue中如何为不同功能设置不同的默认打印设置(设置不同的打印机)

浏览器自带的window.print 功能较简单&#xff0c;这里使用LODOP露肚皮打印 以下是vue2示例&#xff1a; 从官网中下载Lodop和C-Lodop官网主站安装包并安装到本地电脑可以全局搜索电脑找到安装文件LodopFuncs.js&#xff0c;也可以直接复制我贴出来的文件 //用双端口加载主JS…

数据库管理系统的ACID都各自是什么?

本文基于DBMS中ACID属性的概念&#xff0c;这些属性保证了数据库中执行事务时保持数据一致性、完整性和可靠性所。事务是访问并可能修改数据库内容的单一逻辑工作单元。交易使用读写操作访问数据。为了保持数据库的一致性&#xff0c;在事务前后&#xff0c;遵循某些属性。这些…

ssm基于vue搭建的新闻网站+vue

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码请私聊我 需要定制请私聊 目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 [2 系统…

OB_GINS_day3

这里写目录标题 实现当前状态初始化实现预积分的初始化由于此时preintegration_options 是3&#xff08;也就是考虑odo以及earth rotation&#xff09;为预积分的容器添加需要积分的IMU积分因子接下来是添加新的IMU到preintegration中 实现当前状态初始化 这个state_curr的主要…

如何优化kafka和mysql处理百万级消息计算和落库

一.业务场景 最近业务需要&#xff0c;做了性能优化操作。百万级消息在kafka中秒级传输。cpu密集计算分钟级完成&#xff0c;然后在mysql中秒级落库.模型cpu计算提高了1倍&#xff0c;落表速度提高了5倍&#xff0c;2分钟内完成. 如下序列图&#xff1a; 业务系统A发送千级别…