

Axios核心引擎采用分层架构设计,各模块职责明确:
class Axios {
constructor(instanceConfig) {
this.defaults = instanceConfig; // 全局默认配置
this.interceptors = { // 拦截器管理系统
request: new InterceptorManager(),
response: new InterceptorManager()
};
}
}defaults作为全局默认配置。
async request(configOrUrl, config) {
try {
return await this._request(...);
} catch (err) {
// 增强错误堆栈追踪
}
}
_request() {
// 处理参数重载(支持axios(url, config)语法)
// 配置合并(mergeConfig)
// 处理headers(使用AxiosHeaders)
// 构建拦截器链
}axios(url, config)和axios(config)两种调用方式// 请求拦截器链
requestInterceptorChain.unshift(...)
// 响应拦截器链
responseInterceptorChain.push(...)
// 异步执行流程
const chain = [dispatchRequest, undefined];
chain.unshift(...requestInterceptorChain);
chain.push(...responseInterceptorChain);// 无数据方法(GET等)
utils.forEach(['delete', 'get', 'head', 'options'], ...)
// 含数据方法(POST等)
utils.forEach(['post', 'put', 'patch'], function() {
// 生成标准方法和Form表单方法
function generateHTTPMethod(isForm) {...}
})xxxForm方法(自动设置Content-Type)getUri(config) {
// 构建完整URL
buildFullPath(...);
// 参数序列化
buildURL(...);
}该文件作为Axios的核心控制器,协调了配置管理、请求派发、拦截器流水线、方法适配等关键流程,体现了中间件架构的设计思想。
class InterceptorManager {
constructor() {
this.handlers = []; // 拦截器存储容器
}
}
use(fulfilled, rejected, options) {
this.handlers.push({
fulfilled, // 成功回调
rejected, // 失败回调
synchronous: options?.synchronous, // 同步模式标识
runWhen: options?.runWhen // 执行条件判断
});
return this.handlers.length - 1; // 返回索引作为ID
}eject(id) {
if (this.handlers[id]) {
this.handlers[id] = null; // 标记删除而非物理删除
}
}forEach(fn) {
utils.forEach(this.handlers, h => {
if (h !== null) fn(h); // 自动跳过已移除的拦截器
});
}{
fulfilled: (config) => {}, // 成功处理函数
rejected: (error) => {}, // 错误处理函数
synchronous: false, // 是否同步执行
runWhen: (config) => true // 执行条件判断函数
}当与 Axios 核心配合时:
// Axios.js 中的处理逻辑示例
this.interceptors.request.forEach(interceptor => {
if (interceptor.runWhen(config) === false) return;
// 加入执行链...
});export default function dispatchRequest(config) {
throwIfCancellationRequested(config); // 前置取消检查
config.headers = AxiosHeaders.from(config.headers); // 头部标准化
// 请求数据转换
config.data = transformData.call(config, config.transformRequest);
// 自动设置 Content-Type
if (['post', 'put', 'patch'].includes(config.method)) {
config.headers.setContentType('application/x-www-form-urlencoded', false);
}
}const adapter = adapters.getAdapter(config.adapter || defaults.adapter);
return adapter(config).then(...)// 请求数据转换
transformData.call(config, config.transformRequest)
// 响应数据转换
response.data = transformData.call(config, config.transformResponse, response)function onAdapterRejection(reason) {
if (!isCancel(reason)) {
// 处理非取消类错误
if (reason.response) {
reason.response.data = transformData(...)
}
}
return Promise.reject(reason);
}1、取消感知设计:
function throwIfCancellationRequested(config) {
if (config.cancelToken) { /* Check CancelToken */ }
if (config.signal?.aborted) { /* Check AbortSignal */ }
}2、数据转换管道:
// 典型转换流程示例
请求数据 -> transformRequest 数组 -> 网络适配器
响应数据 -> transformResponse 数组 -> 用户接收3、适配器抽象层:
// 适配器注册机制示例
adapters.register('custom', (config) => {
// 自定义网络实现
})
该模块作为 Axios 网络通信的最后一道关口,在确保安全性的同时,为上层提供了统一的网络抽象接口。
class AxiosError extends Error {
constructor(message, code, config, request, response) {
super(message);
// 保留完整错误堆栈
Error.captureStackTrace(this, this.constructor);
// 扩展属性
this.config = config;
this.request = request;
this.response = response;
this.code = code; // 标准化错误码
}
}code 与 status 并存(兼容不同错误来源)。Object.defineProperties(AxiosError, {
ECONNABORTED: {value: 'ECONNABORTED'}, // 连接中止
ETIMEDOUT: {value: 'ETIMEDOUT'}, // 超时错误
ERR_CANCELED: {value: 'ERR_CANCELED'}, // 手动取消
// ...其他 10+ 标准错误码
});Object.defineProperty(AxiosError.prototype, 'isAxiosError', {
value: true // 快速识别标志
});instanceof 检查,避免多实例问题。toJSON() {
return {
message: this.message,
config: utils.toJSONObject(this.config), // 安全序列化
code: this.code,
status: this.status
};
}static from(error, code, config, request, response) {
const axiosError = Object.create(this.prototype);
// 保留原始错误信息
axiosError.cause = error; // Error Cause 标准提案实现
return axiosError;
}cause 属性保留原始错误。
1、上下文完整性:
try {/* 请求 */}
catch (err) {
console.log(err.config.url); // 可追溯出错请求
console.log(err.response.status); // 查看服务端响应
}2、错误码标准化:
if (err.code === AxiosError.ECONNABORTED) {
// 处理连接中止
}3、安全序列化:
// 日志记录时自动过滤敏感信息
JSON.stringify(err)4、错误溯源:
console.log(err.cause); // 查看底层系统错误该错误系统通过标准化、结构化、可追溯的设计,显著提升了异步请求的调试效率和错误处理能力。
const mergeMap = {
url: valueFromConfig2, // 完全使用新配置
method: valueFromConfig2,
data: valueFromConfig2,
baseURL: defaultToConfig2, // 新配置优先
headers: 深度合并策略, // 特殊对象合并
validateStatus: mergeDirectKeys // 条件合并
// ...其他 30+ 配置项策略
};1、新配置优先 (valueFromConfig2)
function valueFromConfig2(_, b) {
return b !== undefined ? clone(b) : undefined;
}urlmethoddata2、默认值优先 (defaultToConfig2)
function defaultToConfig2(a, b) {
return b !== undefined ? clone(b) : clone(a);
}baseURLtimeoutwithCredentials3、深度合并 (mergeDeepProperties)
function mergeDeepProperties(a, b) {
if (均为对象) return 深度合并;
if (b是数组) return 复制新数组;
return b ?? a;
}headers(特殊处理)transformRequesttransformResponse4、条件合并 (mergeDirectKeys)
function mergeDirectKeys(a, b) {
return config2存在该属性 ? 合并值 : 保留config1值;
}validateStatusheaders: (a, b) => mergeDeepProperties(
headersToObject(a),
headersToObject(b),
true // 启用大小写不敏感合并
)Content-Type 与 content-type)。
1、不变性原则
function clone(source) {
if (数组) return source.slice();
if (对象) return {...source};
return source;
}2、安全递归合并:
utils.merge 实现:
- 跳过原型链属性
- 处理循环引用
- 控制合并深度(默认 10 层)3、策略扩展性:
// 自定义合并策略示例
mergeMap.customProp = (a, b) => {
return a + b; // 自定义合并逻辑
}该模块是 Axios 数据转换的核心处理器,负责请求/响应数据的多阶段转换流程。
export default function transformData(fns, response) {
const config = this || defaults; // 获取当前配置
const context = response || config; // 确定执行上下文
const headers = AxiosHeaders.from(context.headers); // 标准化请求头
let data = context.data; // 原始数据
// 执行转换流水线
utils.forEach(fns, function(fn) {
data = fn(data, headers.normalize(), response?.status);
});
return data;
}1、链式传递:
// 示例转换函数队列
const transformRequest = [
data => JSON.stringify(data), // 序列化
data => encryptPayload(data) // 加密
];
// 执行顺序:序列化 -> 加密2、上下文绑定:
fn.call(config, data, headers, status)3、头信息交互:
headers.normalize() // 标准化头信息键名(如 content-type -> Content-Type)1、请求阶段转换:
// 请求处理流程
config.transformRequest.forEach(fn => {
data = fn(data, headers);
});2、响应阶段转换:
// 响应处理流程
config.transformResponse.forEach(fn => {
data = fn(data, headers, status);
});type TransformFunction = (
data: any,
headers: AxiosHeaders,
status?: number
) => any;1、不可变处理:
let data = context.data; // 保留原始数据引用
data = fn(data); // 每次转换创建新数据2、状态感知转换:
// 根据 HTTP 状态码进行不同处理
function statusAwareTransform(data, headers, status) {
if (status >= 400) {
return { error: data };
}
return data;
}3、头信息联动:
function setContentType(data, headers) {
if (typeof data === 'string') {
headers.set('Content-Type', 'text/plain');
}
return data;
}const validateStatus = response.config.validateStatus;
if (!response.status || !validateStatus || validateStatus(response.status)) {
resolve(response);
}三层短路逻辑:
reject(new AxiosError(
'Request failed with status code ' + response.status,
[/*...*/][Math.floor(response.status/100)-4], // 错误类型选择器
response.config,
response.request,
response
));4xx 状态码 ➔ ERR_BAD_REQUEST(客户端错误)。5xx 状态码 ➔ ERR_BAD_RESPONSE(服务端错误)validateStatus 配置自定义状态码验证逻辑。通过对 Core 核心引擎的深度剖析,我们揭示了其分层架构、拦截器链、数据管道三大设计支柱。从网页的配置合并到网页的拦截器机制,每个模块都体现了高内聚低耦合的设计哲学。
收获:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。