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.mzph.cn/pingmian/58579.shtml

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

相关文章

【牛客刷题实战】二叉树遍历

大家好&#xff0c;我是小卡皮巴拉 文章目录 目录 牛客题目&#xff1a; 二叉树遍历 题目描述 输入描述&#xff1a; 输出描述&#xff1a; 示例1 解题思路 问题理解 算法选择 具体思路 解题要点 完整代码&#xff08;C语言&#xff09; 兄弟们共勉 &#xff01;&…

vmvare启动freebsd操作系统密码忘记了怎么办?

本章教程,主要介绍,通过vmvare安装的freebsd操作系统,密码忘记了,如何重置密码。 一、重启虚拟机 在重启过程中,按键盘中是数字2,进入单用户模式。 二、进入到shell界面 在出现“Enter full pathname of shell or RETURN for /bin/sh:”直接按回车键。 三、输入命令 mou…

【设计模式系列】代理模式(八)

一、什么是代理模式 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它为其他对象提供一种代理以控制对这个对象的访问。代理模式在不直接访问实际对象的情况下&#xff0c;提供了对目标对象的间接访问。通过引入一个代理对象来间接操作实际对…

WPS查询函数VLOOKUP,匹配寻找值自动带入值

想实现在下表输入物料名称后&#xff0c;把上表中的单位自动带入 那就要用到VLOOKUP函数&#xff0c;获取第2个表第1列的值后去第1个表的第1列匹配&#xff0c;匹配到后得到行数值&#xff0c;把第1个表的第2列赋值给第2个表的第2列。 Vlookup函数参数为Vlookup(查找值&#…

sqoop问题汇总记录

此篇博客仅记录在使用sqoop时遇到的各种问题。持续更新&#xff0c;有问题评论区一起探讨&#xff0c;写得有不足之处见谅。 Oracle_to_hive 1. main ERROR Could not register mbeans java.security.AccessControlException: access denied ("javax.management.MBeanTr…

简单说明vuex

vuex 知识结构配置调用 知识结构 vue用于管理公共数据的仓库 配置 state&#xff1a;所有公共数据的初始状态&#xff08;初始值&#xff09; export default {state: {count: 0,} };mutations&#xff1a;修改state内容的方法&#xff08;必须为同步方法&#xff09; export …

分类算法——决策树 详解

决策树的底层原理 决策树是一种常用的分类和回归算法&#xff0c;其基本原理是通过一系列的简单决策&#xff0c;将数据集划分为多个子集&#xff0c;从而实现分类。决策树的核心思想是通过树形结构表示决策过程&#xff0c;节点代表特征&#xff0c;边代表决策&#xff0c;叶子…

Nature Electronics 用于语音识别的液体声传感器,基于悬浮在载液的钕-铁-硼磁性纳米颗粒

近年来&#xff0c;工程师们开发了一系列越来越复杂的传感器&#xff0c;用于机器人、便携式、可穿戴甚至植入式监测。然后&#xff0c;可以使用最先进的机器学习来分析这些传感器收集的数据&#xff0c;使设备能够识别音频中的特定声音、图像中的对象或其他信息。加州大学洛杉…

NVR批量管理软件/平台EasyNVR多个NVR同时管理支持视频投放在电视墙上

在当今智能化、数字化的时代&#xff0c;视频监控已经成为各行各业不可或缺的一部分&#xff0c;无论是公共安全、交通管理、企业监控还是智慧城市建设&#xff0c;都离不开高效、稳定的视频监控系统的支持。而在这些应用场景中&#xff0c;将监控视频实时投放到大屏幕电视墙上…

【GeoJSON在线编辑平台】(0)项目启动与前言

前言 事情是这样的…… 有这么一个项目&#xff0c;需要开发一个在线的标注平台。以天地图为底图&#xff0c;在天地图上标注出一些特征地物&#xff0c;比如描出农田耕地房屋建筑之类的要素。 这个需求简化一下其实就是一个在线的矢量编辑平台&#xff0c;通过绘制多边形功能…

豆包,攻克数字是个什么工具?《GKData-挖掘数据的无限可能》(数据爬虫采集工具)

豆包&#xff0c;攻克数字是个什么工具&#xff1f; “攻克数字” 指的是 “攻克数字&#xff08;GKData&#xff09;” 这样一款工具。是一款针对网页、APP中数据自动解析转表存入数据库的软件&#xff0c;为数据工作者而生。它是一个不会编程也能用的可视化数据解析为标准二…

【Python】实战:使用input()获取一个字符串,编写并传参,将字符串中所有的小写字母转成大写字母,将大写字母转成小写字母

#使用input()获取一个字符串&#xff0c;编写并传参&#xff0c;将字符串中所有的小写字母转成大写字母&#xff0c;将大写字母转成小写字母 #使用input()获取一个字符串&#xff0c;编写并传参&#xff0c;将字符串中所有的小写字母转成大写字母&#xff0c;将大写字母转成小…

【成都新篇】龙信科技电子取证实验室,引领科技取证新时代

文章关键词&#xff1a;电子数据取证实验室、手机取证、介质取证、云取证、现场勘查、电子物证 在科技创新的浪潮中&#xff0c;龙信科技成都实验室以其卓越的电子数据取证服务&#xff0c;成为了中西部地区一颗璀璨的明珠。随着新址的搬迁&#xff0c;我们不仅扩大了业务范围…

【C/C++】字符/字符串函数(1)——由string.h提供

零.导言 什么是字符/字符串函数呢&#xff1f; 其实就是一类用于处理字符和字符串的函数。 而其中一部分函数包含在头文件 string.h 中&#xff0c;有 strlen strcpy strcat strcmp strncpy strncat strncmp strstr strtok strerror 等等 接下来我将逐个讲解这些函数。 一.str…

硅谷甄选(11)角色管理

角色管理模块 10.1 角色管理模块静态搭建 还是熟悉的组件&#xff1a;el-card、el-table 、el-pagination、el-form <template><el-card><el-form :inline"true" class"form"><el-form-item label"职位搜索"><el-…

鸿蒙UI开发——基于全屏方案实现沉浸式界面

1、概 述 典型应用全屏窗口UI元素包括状态栏、应用界面和底部导航条。 其中状态栏和导航条&#xff0c;通常在沉浸式布局下称为避让区&#xff0c;避让区之外的区域称为安全区。 开发应用沉浸式效果主要指&#xff1a;通过调整状态栏、应用界面和导航条的显示效果来减少状态…

有没有优质的公司可以提供高质量大模型数据?

在当今的机器学习和人工智能领域&#xff0c;大模型&#xff08;Big Model&#xff09;已成为处理大规模数据和复杂任务的重要工具。本文将探讨大模型的基本概念、为什么大模型需要数据&#xff0c;以及高质量大数据的标准&#xff0c;并介绍一些可能提供优质大模型数据的公司。…

规划误差降低27%,碰撞率降低33%Senna: 大规模视觉-语言模型与端到端自动驾驶相结合

Abstract 端到端自动驾驶在大规模数据中展示了强大的规划能力&#xff0c;但在复杂、罕见的场景中仍然因常识有限而表现不佳。相比之下&#xff0c;大型视觉语言模型&#xff08;LVLMs&#xff09;在场景理解和推理方面表现出色。前进的方向在于融合两者的优势。以往利用LVLMs…

openpnp - 手工修改配置文件(元件高度,size,吸嘴)

文章目录 openpnp - 手工修改配置文件(元件高度,size,吸嘴)概述笔记parts.xmlpackages.xml 手工将已经存在的NT1,NT2拷贝出来改名备注END openpnp - 手工修改配置文件(元件高度,size,吸嘴) 概述 载入新板子贴片准备时&#xff0c;除了引入Named CSV文件&#xff0c;还要在ope…

硬件电子器件学习笔记

系列文章目录 文章目录 系列文章目录电阻碳质电阻器线绕电阻 变压器自耦变压器隔离变压器 电阻 碳质电阻器 CCR&#xff1a; 优点&#xff1a;体积大&#xff0c;吸收脉冲电流、防浪涌。缺点&#xff1a;温度系数、稳定性差、吸水后也会变化、随着使用会变化。 医用除颤仪可…