深入解读axios源码
# 深入解读axios源码
axios是一个基于Promise来管理的http请求库,本质上来说axios是对原生XHR的封装,是其基于Promise的实现版本,相对于Ajax的回调函数有更加好的链式异步操作管理。
axios的主要特性包括:
- 基于 Promise API
- 支持浏览器和node运行环境
- 提供数据拦截器和数据格式转换
- 提供请求取消功能
- 可自定义数据请求方式
- 自动转换JSON数据
- 支持客户端防范XSRF
# 项目目录结构
/lib
├── adapters # 请求发送适配器
│ ├── http.js # node环境http请求对象
│ └── xhr.js # 浏览器环境XML请求对象
├── axios.js # 入口,创建构造函数
├── cancel # 定义取消功能
├── core # 核心代码
│ ├── Axios.js # axios实例构造函数
│ ├── InterceptorManager.js # 拦截器管理
│ ├── createError.js # 抛出错误
│ ├── dispatchRequest.js # 请求分发
│ ├── enhanceError.js # 错误更新处理
│ ├── mergeConfig.js # 合并配置参数
│ ├── settle.js # 根据返回状态码返回promise
│ └── transformData.js # 数据传参格式转换
├── defaults.js # 默认配置
├── helpers # 辅助类方法
└── utils.js # 工具类方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 入手准备
// package.json
{
"name": "axios",
"version": "0.21.0",
"description": "Promise based HTTP client for the browser and node.js",
"main": "index.js", // 主入口文件
...
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
入口文件
// index.js
module.exports = require('./lib/axios');
1
2
2
# axios 函数定义
// lib/axios.js
'use strict';
var utils = require('./utils');
var bind = require('./helpers/bind');
var Axios = require('./core/Axios');
var mergeConfig = require('./core/mergeConfig');
var defaults = require('./defaults');
function createInstance(defaultConfig) {
// 创建 Axios 构造函数实例
var context = new Axios(defaultConfig);
// 通过 bind 函数定义 instance 为调用 Axios.prototype.request 的函数
// 也是调用axios是调用 Axios.prototype.request 函数的原因
var instance = bind(Axios.prototype.request, context);
// 复制 Axios 上的原型方法到 instance 上,包括request、get、post..等方法
// 并修改 this 指针为指向 context
utils.extend(instance, Axios.prototype, context);
// 复制 context 到 intance 上
// 复制默认配置和拦截器
utils.extend(instance, context);
return instance;
}
// 创建默认导出实例
var axios = createInstance(defaults);
// 导出Axios类,允许继承扩展
axios.Axios = Axios;
// 定义用于创建 axios 实例的工厂函数
axios.create = function create(instanceConfig) {
return createInstance(mergeConfig(axios.defaults, instanceConfig));
};
// 绑定取消请求相关方法
axios.Cancel = require('./cancel/Cancel');
axios.CancelToken = require('./cancel/CancelToken');
axios.isCancel = require('./cancel/isCancel');
// 绑定用户并行处理的静态方法
axios.all = function all(promises) {
return Promise.all(promises);
};
axios.spread = require('./helpers/spread');
// 绑定是否为 axios 内部错误方法
axios.isAxiosError = require('./helpers/isAxiosError');
module.exports = axios;
// 允许使用Ts 中的 default import 语法
module.exports.default = axios;
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
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