1.区别一般http请求与ajax请求
- ajax 请求是一种特别的 http 请求
- 对服务器端来说, 没有任何区别, 区别在浏览器端
- 浏览器端发请求: 只有 XHR 或 fetch 发出的才是 ajax 请求, 其它所有的都是
非 ajax 请求 - 浏览器端接收到响应
(1) 一般请求: 浏览器一般会直接显示响应体数据, 也就是我们常说的刷新/
跳转页面
(2) ajax 请求: 浏览器不会对界面进行任何更新操作, 只是调用监视的回调
函数并传入响应相关数据
2.axios
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
中文文档:www.axios-js.com/zh-cn/docs/
3.源码分析
3.1 源码目录结构
├── /dist/ # 项目输出目录
├── /lib/ # 项目源码目录
│ ├── /adapters/ # 定义请求的适配器 xhr、 http
│ │ ├── http.js # 实现 http 适配器(包装 http 包)
│ │ └── xhr.js # 实现 xhr 适配器(包装 xhr 对象)
│ ├── /cancel/ # 定义取消功能
│ ├── /core/ # 一些核心功能
│ │ ├── Axios.js # axios 的核心主类
│ │ ├── dispatchRequest.js # 用来调用 http 请求适配器方法发送请求的函数
│ │ ├── InterceptorManager.js # 拦截器的管理器
│ │ └── settle.js # 根据 http 响应状态, 改变 Promise 的状态
│ ├── /helpers/ # 一些辅助方法
│ ├── axios.js # 对外暴露接口
│ ├── defaults.js # axios 的默认配置
│ └── utils.js # 公用工具
├── package.json # 项目信息
├── index.d.ts # 配置 TypeScript 的声明文件
└── index.js # 入口文件
入口文件直接引用lib/axios.js
3.2 源码浅析
3.2.1axios请求
在axios.js中
可以看出
- axios 是 Axios.prototype.request 函数 bind()返回的函数
- 同时 axios 作为对象有 Axios 原型对象上的所有方法, 有 Axios 对象上所有属性
- 换句话讲, 从语法上来说: axios 不是 Axios 的实例 ,从功能上来说: axios 是 Axios 的实例
- 这样axios就对应了文档中既可以通过向
axios传递相关配置来创建请求,也可以通过别名进行便捷请求
3.2.1.1 创建实例
文档中创建实例:
根据指定配置创建一个新的 axios, 也就就每个新 axios 都有自己的配置
基本用法:
(1) 需求: 项目中有部分接口需要的配置与另一部分接口需要的配置不太一
样, 如何处理
(2) 解决: 创建 2 个新 axios, 每个都有自己特有的配置, 分别应用到不同要
求的接口请求中
源码:
和创建axios使用相同的函数。因此相同点
(1) 都是一个能发任意请求的函数: request(config)
(2) 都有发特定请求的各种方法: get()/post()/put()/delete()
(3) 都有默认配置和拦截器的属性: defaults/interceptors
又因为传入的配置可能不同,同时create函数之下的函数在返回的axios并不存在,不同点
(1) 默认匹配的值很可能不一样
(2) instance 没有 axios 后面添加的一些方法: create()/CancelToken()/all()
3.2.2 Axios.prototype.request()
上一节可知,axios函数执行的是Axios.prototype.request()函数。
在lib/core/Axios.js中我们可以看到Axios.prototype.request()函数
源码:
request(config)函数执行流程:
将请求拦截器 / dispatchRequest() / 响应拦截器 通过 promise 链串连起来,返回 promise 。
通过操作数组chain,配合promise链式执行数组中的函数。
首先将请求拦截器unshift到数组,再将响应拦截器push到数组,这样就决定了当有多个拦截器时的执行顺序。
如图,多个拦截器的执行顺序。
**3.2.3 dispatchRequest(config)函数 **
dispatchRequest(config)函数执行流程:
转换请求数据 ===> 调用 xhrAdapter()发请求 ===> 请求返回后转换响应数据,返回 promise 。
数据转换:
源码:
默认配置(defaults.js)
请求数据转换:
响应数据转换: