返回

Axios的底层秘密:封装Promise的异步请求模块

前端

Axios是一个前端非常流行的异步请求模块,它最大的亮点在于语法糖非常好用,而且封装了各种便捷的功能。比如默认配置、超时时间、请求拦截器、响应拦截器等。很多开发者在使用Axios的时候都只用到了这些语法糖,而对于Axios的底层源码却并不了解。

但其实,了解Axios的底层源码可以帮助我们更合理的配置Axios,也可以更快的定位请求失败时的异常。

目录结构

首先,我们来看一下Axios的目录结构。

axios
├── axios.js
├── axios.min.js
├── changelog.md
├── dist
│   ├── axios.js
│   ├── axios.min.js
├── lib
│   ├── adapters
│   │   ├── browser.js
│   │   ├── http.js
│   │   ├── node.js
│   │   ├── xhr.js
│   │   └── xhr2.js
│   ├── cancel
│   │   ├── cancel.js
│   │   ├── Cancel.js
│   │   ├── CancelToken.js
│   │   └── isCancel.js
│   ├── core
│   │   ├── buildURL.js
│   │   ├── cache.js
│   │   ├── defaults.js
│   │   ├── enhanceError.js
│   │   ├── intercept.js
│   │   ├── jsonp.js
│   │   ├── mergeConfig.js
│   │   ├── node/index.js
│   │   ├── params.js
│   │   ├── settle.js
│   │   ├── transformResponse.js
│   │   ├── transformRequest.js
│   │   ├── url.js
│   │   └── validateStatus.js
│   ├── helpers
│   │   ├── bind.js
│   │   ├── buildFullPath.js
│   │   ├── forEach.js
│   │   ├── isArray.js
│   │   ├── isBoolean.js
│   │   ├── isBuffer.js
│   │   ├── isFormData.js
│   │   ├── isFunction.js
│   │   ├── isNumber.js
│   │   ├── isObject.js
│   │   ├── isPlainObject.js
│   │   ├── isString.js
│   │   ├── isUndefined.js
│   │   ├── merge.js
│   │   ├── parseHeaders.js
│   │   ├── reduce.js
│   │   ├── settle.js
│   │   ├── toFormData.js
│   │   ├── type.js
│   │   ├── uniqueDomain.js
│   │   └── url.js
│   ├── index.js
│   ├── package-lock.json
│   ├── package.json
│   ├── README.md
├── src
│   ├── cancel
│   │   ├── cancel.js
│   │   ├── Cancel.js
│   │   ├── CancelToken.js
│   │   └── isCancel.js
│   ├── core
│   │   ├── buildURL.js
│   │   ├── cache.js
│   │   ├── defaults.js
│   │   ├── enhanceError.js
│   │   ├── intercept.js
│   │   ├── jsonp.js
│   │   ├── mergeConfig.js
│   │   ├── node/index.js
│   │   ├── params.js
│   │   ├── settle.js
│   │   ├── transformResponse.js
│   │   ├── transformRequest.js
│   │   ├── url.js
│   │   └── validateStatus.js
│   ├── helpers
│   │   ├── bind.js
│   │   ├── buildFullPath.js
│   │   ├── forEach.js
│   │   ├── isArray.js
│   │   ├── isBoolean.js
│   │   ├── isBuffer.js
│   │   ├── isFormData.js
│   │   ├── isFunction.js
│   │   ├── isNumber.js
│   │   ├── isObject.js
│   │   ├── isPlainObject.js
│   │   ├── isString.js
│   │   ├── isUndefined.js
│   │   ├── merge.js
│   │   ├── parseHeaders.js
│   │   ├── reduce.js
│   │   ├── settle.js
│   │   ├── toFormData.js
│   │   ├── type.js
│   │   ├── uniqueDomain.js
│   │   └── url.js
│   ├── index.js
│   ├── package-lock.json
│   ├── package.json
│   ├── README.md
└── test
    ├── browser-env.js
    ├── default-adapter.test.js
    ├── helpers.test.js
    ├── index.js
    ├── integrate
    │   ├── axios.test.js
    │   ├── cancelled-promise.test.js
    │   ├── canceled-request.test.js
    │   ├── clean-up-interceptor.test.js
    │   ├── custom-adapters.test.js
    │   ├── downloads-progress.test.js
    │   ├── form-data.test.js
    │   ├── http-status-codes.test.js
    │   ├── intercept-response.test.js
    │   ├── json-body.test.js
    │   ├── jsonp-request.test.js
    │   ├── merge-configs.test.js
    │   ├── node-http-adapter.test.js
    │   ├── redirect-config.test.js
    │   ├── redirects.test.js
    │   ├── relative-urls.test.js
    │   ├── response-transform.test.js
    │   ├── timeout-config.test.js
    │   └── xhr-adapter.test.js
    ├── node
    │   ├── buildURL.test.js
    │   ├── cache.test.js
    │   ├── defaults.test.js
    │   ├── enhanceError.test.js
    │   ├── intercept.test.js
    │   ├── jsonp.test.js
    │   ├── mergeConfig.test.js
    │   ├── params.test.js
    │   ├── request.test.js
    │   ├── settle.test.js
    │   ├── transformResponse.test.js
    │   ├── transformRequest.test.js
    │   ├── url.test.js
    │   └── validateStatus.test.js
    ├── process-abort.test.js
    ├── progress-event.test.js
    ├── README.md
    ├── type-checking.test.js
    └── xhr-adapter-sync.test.js

从目录结构可以看出,Axios的代码组织非常清晰。核心代码都在lib文件夹下,而src文件夹下是源代码,test文件夹下是测试代码。

语法糖

Axios最出名的就是它的语法糖了。这些语法糖让Axios的使用非常方便。比如,我们可以使用以下代码来发送一个GET请求:

axios.get('/user').then((response) => {
  console.log(response.data);
});

这段代码非常简单,但它却做了很多事情。首先,它创建了一个新的Axios实例。然后,它使用get()方法发送了一个GET请求。最后,它使用then()方法来处理请求的响应。

Axios还提供了很多其他语法糖,比如post()put()delete()patch()等。这些语法糖都非常方便,可以让我们轻松地发送各种类型的请求。

Axios的常用API

除了语法糖之外,Axios还提供了一些非常有用的API。这些API可以让我们更轻松地处理请求和响应。

比如,我们可以使用interceptors来设置请求和响应拦截器。拦截器可以让我们在请求发送之前或响应返回之后做一些事情。

axios.interceptors.request.use((config) => {
  // 在请求发送之前做一些事情
  return config;
}, (error) => {
  // 在请求发送失败时做一些事情
  return Promise.reject(error);
});
axios.interceptors.response.use((response) => {
  // 在响应返回之后做一些事情
  return response;
}, (error) => {
  // 在响应返回失败时做一些事情
  return Promise.reject(error);
});

我们还可以使用transformRequesttransformResponse来转换请求和响应的数据。这可以让我们轻松地对数据进行格式化或加密。

axios.defaults.transformRequest