HTTP 请求库 - Axios 源码分析

前言

说到 JS HTTP 请求,就不得不提 Axios,作为前端网络请求库领域中的霸主,被广泛应用于众多的 web 项目中。

几款热门 HTTP 请求库在 GitHub 上的受欢迎程度

热门 JS HTTP 请求库 特性简介 Star Fork
Axios 基于 Promise,支持浏览器和 node 85.4k 8.3k
Request 不基于 Promise,简化版的 HTTP 25.2k 3.1k
Fetch 基于 Promise,不支持 node 调用 24.8k 3k
Superagent
15.7k 1.3k

虽然大家都是对 XMLHttpRequest 的封装,但是纵观 Axios 的热度,一骑绝尘啊!由此可见,Axios 真的是一个很优秀的开源项目。然而惭愧的是日常开发中总是拿来就用,一直没有静下心来好好拜读一番 Axios 的源码,会不会有很多人跟我一样呢?这里先列举一下 axios 项目的核心目录结构:

lib

└─ adapters

   ├─ http.js // node 环境下利用 http 模块发起请求

   ├─ xhr.js // 浏览器环境下利用 xhr 发起请求

└─ cancel

   ├─ Cancel.js

   ├─ CancelToken.js

   ├─ isCancel.js

└─ core

    ├─ Axios.js // 生成 Axios 实例

    ├─ InterceptorManager.js // 拦截器

    ├─ dispatchRequest.js  // 调用适配器发起请求

    ...

└─ helpers

    ├─ mergeConfig.js // 合并配置

    ├─ ...

├─ axios.js  // 入口文件

├─ defaults.js  // axios 默认配置项

├─ utils.js

简介

Axios 是一个基于 Promise 网络请求库,作用于 node.js 和浏览器中。在服务端它使用原生 node.jshttp模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。特性:

  • 从浏览器创建XMLHttpRequests

  • 从 node.js 创建http请求

  • 支持PromiseAPI

  • 拦截请求和响应

  • 转换请求和响应数据

  • 取消请求

  • 自动转换 JSON 数据

  • 客户端支持防御XSRF

Axios 内部运作流程

image_8ae50529.png接下来我们结合 axios 的运作流程一起来剖析以下几个模块:

  • Axios 构造函数
  • 请求 / 响应拦截器
  • dispatchRequest 派发请求
  • 转换请求 / 响应数据
  • 适配器处理 HTTP 请求

Axios 如何支持不同的使用方式?

使用 axios 发起请求

我们先来回忆一下平时是如何使用 axios 的:

// 方式 1  axios(config)

axios({
   

    method: 'get',

    url: 'xxx',

    data: {
   }

});



// 方式 2  axios(url[, config]),默认 get 请求

axios('http://xxx');



// 方式 3 使用别名进行请求

axios.request(config)

axios.get(url[, config])

axios.post(url[, data[, config]])

axios.put(url[, data[, config]])

...



// 方式 4 创建 axios 实例,自定义配置

const instance = axios.create({
   

  baseURL: 'https://some-domain.com/api/',

  timeout: 1000,

  headers: {
   'X-Custom-Header': 'foobar'}

});



axios#request(config)

axios#get(url[, config])

axios#post(url[, data[, config]])

axios#put(url[, data[, config]])

...

源码分析

首先来看 axios 的入口文件, lib 目录下的axios.js:

// /lib/axios.js

function createInstance(defaultConfig) {
   

  // 创建 axios 实例

  var context = new Axios(defaultConfig);

  // 把 instance 指向 Axios.prototype.request 方法

  var instance = bind(Axios.prototype.request, context);

  // 把 Axios.prototype 上的方法扩展到 instance 上,指定上下文是 context

  utils.extend(instance, Axios.prototype, context);

  // 把 context 上的方法扩展到 instance 上

  utils.extend(instance, context);

  // 导出 instance 对象

  return instance;

}

var axios = createInstance(defaults);

// 添加 create 方法,返回 createInstance 函数,参数为自定义配置 + 默认配置

axios.create = function create(instanceConfig) {
   

  return createInstance(mergeConfig(axios.defaults, instanceConfig));

};



...



module.exports = axios;

// Allow use of default import syntax in TypeScript

module.exports.default = axios;

可见,当我们调用axios()时,实际上是执行了createInstance返回的一个指向Axios.prototype.request的函数;通过添加create方法支持用户自定义配置创建,并且最终也是执行了Axios.prototype.request方法;接下来我们看看Axios.prototyp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值