深入解读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

# 入手准备

// 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

入口文件

// index.js
module.exports = require('./lib/axios');
1
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
上次更新: 2022/7/5 下午5:18:20