dispatchRequest
上篇文章中说到,在lib/core/Axios.js
中有用到 dispatchRequest 方法,这个方法就用于发起请求,并返回一个 Promise: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
65lib/core/dispatchRequest.js
module.exports = function dispatchRequest(config) {
// 请求取消相关
throwIfCancellationRequested(config);
// 如果配置了 baseURL,这里会做处理
if (config.baseURL && !isAbsoluteURL(config.url)) {
config.url = combineURLs(config.baseURL, config.url);
}
// 保证请求头的存在
config.headers = config.headers || {};
// 转换请求数据
config.data = transformData(
config.data,
config.headers,
config.transformRequest
);
// Flatten headers
config.headers = utils.merge(
config.headers.common || {},
config.headers[config.method] || {},
config.headers || {}
);
utils.forEach(
['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
function cleanHeaderConfig(method) {
delete config.headers[method];
}
);
// 使用用户配置的 adapter 或默认的 adapter
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
);
}
}
return Promise.reject(reason);
});
};
dispatchRequest 方法比较简单,主要是处理请求数据,并调用 adapter 方法发起请求。
adapter 方法
1 | var adapter = config.adapter || defaults.adapter; |
用户可以自定义 adapter,如果没有的话则是用默认的 adapter 方法,这个我在第一篇文章的末尾有提到:1
2
3
4
5
6
7
8
9
10
11
12function getDefaultAdapter() {
var adapter;
// Node.js 有 process,可以依此来判断 Node.js 环境
if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
// node 使用 http
adapter = require('./adapters/http');
} else if (typeof XMLHttpRequest !== 'undefined') {
// 浏览器使用 XHR
adapter = require('./adapters/xhr');
}
return adapter;
}
axios 会根据环境的不同引入不同的代码,浏览器下为 xhr.js,Node.js 下为 http.js,先看 xhr.js:
lib/adapters/xhr.js
1 | module.exports = function xhrAdapter(config) { |
xhr.js 返回了一个 Promise,在 Promise 中 实例化 xhr new XMLHttpRequest()
,监听 onreadystatechange
事件,再处理各种配置参数,最后调用 send
方法,发起请求。
lib/adapters/http.js
1 | var isHttps = /https:?/; |
http.js 整体返回也是一个 Promise,不过内部使用了 Node.js 的 http 与 https 模块,对参数进行处理后发起请求。