axios之Axios.js源码

Axios

Axios.js 是 Axios 的核心文件,位于 lib/core/Axios.js

文件定义了一个 Axios 类,负责整个请求生命周期的管理。包含了 requestgetpost 等发起请求的核心逻辑

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
import utils from '../utils.js';
import buildURL from '../helpers/buildURL.js';
import InterceptorManager from './InterceptorManager.js';
import dispatchRequest from './dispatchRequest.js';
import mergeConfig from './mergeConfig.js';
import buildFullPath from './buildFullPath.js';
import validator from '../helpers/validator.js';
import AxiosHeaders from './AxiosHeaders.js';
import transitionalDefaults from '../defaults/transitional.js';

const validators = validator.validators;

class Axios {
constructor(instanceConfig) {
// 存储实例的默认配置(如 baseURL、headers、timeout 等)
this.defaults = instanceConfig || {};
// Axios 拦截器管理器
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager(),
};
}

async request(configOrUrl, config) {
try {
return await this._request(configOrUrl, config);
} catch (err) {
// 错误堆栈增强处理
if (err instanceof Error) {
let dummy = {};

Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error());
// 提取Error堆栈信息
const stack = (() => {
if (!dummy.stack) {
return '';
}
// 获取Error堆栈信息的第一个换行符号索引位置
const firstNewlineIndex = dummy.stack.indexOf('\n');
// 提取Error堆栈信息,去掉Error: ... 这一行
return firstNewlineIndex === -1 ? '' : dummy.stack.slice(firstNewlineIndex + 1);
})();
try {
if (!err.stack) {
err.stack = stack;
// match without the 2 top stack lines
} else if (stack) {
// 获取Error堆栈信息的第一个换行符号索引位置
const firstNewlineIndex = stack.indexOf('\n');
// 获取Error堆栈信息的第二个换行符号索引位置
const secondNewlineIndex =
firstNewlineIndex === -1 ? -1 : stack.indexOf('\n', firstNewlineIndex + 1);
// 提取无首两行的Error堆栈信息
const stackWithoutTwoTopLines =
secondNewlineIndex === -1 ? '' : stack.slice(secondNewlineIndex + 1);
// 合并堆栈
if (!String(err.stack).endsWith(stackWithoutTwoTopLines)) {
err.stack += '\n' + stack;
}
}
} catch (e) {
// ignore the case where "stack" is an un-writable property
}
}

throw err;
}
}

_request(configOrUrl, config) {
// 支持 axios(url, {...}), axios({url, ...})调用
if (typeof configOrUrl === 'string') {
config = config || {};
config.url = configOrUrl;
} else {
config = configOrUrl || {};
}
// 合并默认配置和用户配置
config = mergeConfig(this.defaults, config);

const { transitional, paramsSerializer, headers } = config;

if (transitional !== undefined) {
// 验证过渡性配置是否为布尔值
validator.assertOptions(
transitional,
{
silentJSONParsing: validators.transitional(validators.boolean),
forcedJSONParsing: validators.transitional(validators.boolean),
clarifyTimeoutError: validators.transitional(validators.boolean),
legacyInterceptorReqResOrdering: validators.transitional(validators.boolean),
},
false
);
}

if (paramsSerializer != null) {
// 验证参数序列化器是否为函数或对象
if (utils.isFunction(paramsSerializer)) {
// https://github.com/axios/axios/commit/a56c8661209d5ce5a645a05f294a0e08a6c1f6b3
// 兼容老版本的参数序列化器函数
config.paramsSerializer = {
serialize: paramsSerializer,
};
} else {
// 验证 encode 和 serialize 是否为函数
validator.assertOptions(
paramsSerializer,
{
encode: validators.function,
serialize: validators.function,
},
true
);
}
}

// 设置config.allowAbsoluteUrls的默认值
// 决定绝对 URL 是否可以覆盖已配置的 baseUrl。
// 设置为 true(默认值)时,绝对 url 会覆盖 baseUrl;
// 设置为 false 时,绝对 url 始终会拼接在 baseUrl 之后。
if (config.allowAbsoluteUrls !== undefined) {
// do nothing
} else if (this.defaults.allowAbsoluteUrls !== undefined) {
config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls;
} else {
// 默认允许绝对URL
config.allowAbsoluteUrls = true;
}

validator.assertOptions(
config,
{
// 验证 baseUrl 拼写
baseUrl: validators.spelling('baseURL'),
// 验证 withXsrfToken 拼写
withXsrfToken: validators.spelling('withXSRFToken'),
},
true
);

// 设置config.method,设置为小写格式,默认值为 'get'请求
config.method = (config.method || this.defaults.method || 'get').toLowerCase();

// 合并 common 和当前方法对应的 headers
let contextHeaders = headers && utils.merge(headers.common, headers[config.method]);

// 删除所有方法特定的 headers 对象
headers &&
utils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch', 'common'], (method) => {
delete headers[method];
});
// 得到普通 headers 对象
config.headers = AxiosHeaders.concat(contextHeaders, headers);

// 构建请求拦截器链
const requestInterceptorChain = [];
// 是否同步执行请求拦截器
let synchronousRequestInterceptors = true;
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
// 过滤出需要执行的拦截拦截器
if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {
return;
}
// 检查是否所有拦截器都是同步的
synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;

// 获取 transitional 配置
const transitional = config.transitional || transitionalDefaults;
// 获取 legacyInterceptorReqResOrdering 配置
const legacyInterceptorReqResOrdering =
transitional && transitional.legacyInterceptorReqResOrdering;
// 如果 legacyInterceptorReqResOrdering 为 true,请求拦截器后注册先执行,默认该模式
if (legacyInterceptorReqResOrdering) {
requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);
} else {
// 否则,请求拦截器先注册先执行
requestInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);
}
});

// 构建响应拦截器链
const responseInterceptorChain = [];
// 响应拦截器总是按注册顺序存储
this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);
});

let promise;
let i = 0;
let len;

// 异步模式 - Promise 链
if (!synchronousRequestInterceptors) {
// 实际请求任务
const chain = [dispatchRequest.bind(this), undefined];
// 插入请求拦截器
chain.unshift(...requestInterceptorChain);
// 插入响应拦截器
chain.push(...responseInterceptorChain);
len = chain.length;

promise = Promise.resolve(config);

// 遍历链,执行每个拦截器
// [reqFulfilled1, reqRejected1, ..., dispatchRequest, respFulfilled1, respRejected1, ...]
while (i < len) {
promise = promise.then(chain[i++], chain[i++]);
}
// 实际形成的 Promise 链:
// Promise.resolve(config)
// .then(reqFulfilled1, reqRejected1)
// .then(reqFulfilled2, reqRejected2)
// .then(dispatchRequest, undefined)
// .then(resFulfilled1, resRejected1)
// .then(resFulfilled2, resRejected2)
return promise;
}

// 同步模式 - 直接调用
// 获取请求拦截器链的长度
len = requestInterceptorChain.length;
// 获取config配置
let newConfig = config;

// 遍历请求拦截器链,同步执行每个拦截器
while (i < len) {
const onFulfilled = requestInterceptorChain[i++];
const onRejected = requestInterceptorChain[i++];
try {
// // 同步调用,修改配置
newConfig = onFulfilled(newConfig);
} catch (error) {
// 如果请求拦截器抛出错误,调用拒绝回调
onRejected.call(this, error);
// 出错后中断循环
break;
}
}

try {
// 处理后的配置发送请求
promise = dispatchRequest.call(this, newConfig);
} catch (error) {
// 如果 dispatchRequest 同步抛出错误
return Promise.reject(error);
}

i = 0;
// 获取响应拦截器链的长度
len = responseInterceptorChain.length;

// 遍历响应拦截器链,异步执行响应拦截器
while (i < len) {
promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]);
}

// 实际形成的 Promise 链:
// Promise.resolve(config)
// .then(dispatchRequest, undefined)
// .then(resFulfilled1, resRejected1)
// .then(resFulfilled2, resRejected2)
return promise;
}

// 获取完整 URL
getUri(config) {
// 合并默认配置和用户配置
config = mergeConfig(this.defaults, config);
// 构建完整路径
const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
// 构建 URL
return buildURL(fullPath, config.params, config.paramsSerializer);
}
}

// 支持[delete, get, head, options, post, put, patch]请求方法
utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
/*eslint func-names:0*/
Axios.prototype[method] = function (url, config) {
return this.request(
mergeConfig(config || {}, {
method,
url,
data: (config || {}).data,
})
);
};
});

// 支持[post, put, patch, postForm, putForm, patchForm]请求方法
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
function generateHTTPMethod(isForm) {
return function httpMethod(url, data, config) {
return this.request(
mergeConfig(config || {}, {
method,
headers: isForm
? {
'Content-Type': 'multipart/form-data',
}
: {},
url,
data,
})
);
};
}

Axios.prototype[method] = generateHTTPMethod();

Axios.prototype[method + 'Form'] = generateHTTPMethod(true);
});

// 导出 Axios 类
export default Axios;

this.defaults

this.defaults 是一个对象,包含了 Axios 实例的默认配置。它在实例化时通过 createInstance(defaults) 进行设置。这个属性用于存储实例的默认配置。

1
2
3
4
5
6
7
8
// axios.js

function createInstance(defaultConfig) {
const context = new Axios(defaultConfig);
...
}

const axios = createInstance(defaults);

defaults-config

Error.captureStackTrace

Error.captureStackTraceNode.js 中的一个方法,它用于自定义错误堆栈跟踪的格式。方法可以接受两个参数:

  • targetObject:这是你想要自定义堆栈跟踪的错误对象。
  • constructorOpt: 这是一个可选参数,通常是一个函数,用于指示堆栈跟踪应该从哪个函数开始捕获。如果不提供,堆栈跟踪将包括到 Error.captureStackTrace 被调用的位置。
普通错误 (normal-error) 捕获堆栈错误 (capture-error)
normal-error capture-error

增强堆栈的作用:让错误堆栈包含调用 axios() 的位置,而不仅仅是内部的 _request,可以看到错误发生在业务代码的哪一行。


axios之Axios.js源码
https://www.my-web.cn/axios/Axios-class/
发布于
2026年5月11日
许可协议