axios--源码解析

源码目录结构

源码分析

axios与Axios的关系?

  1. 从语法上来说: axios不是Axios的实例
  2. 从功能上来说: axios是Axios的实例
  3. axios是Axios.prototype.request函数bind()返回的函数
  4. axios作为对象有Axios原型对象上的所有方法, 有Axios对象上所有属性

instance与axios的区别?

  1. 相同:
    (1) 都是一个能发任意请求的函数: request(config)
    (2) 都有发特定请求的各种方法: get()/post()/put()/delete()
    (3) 都有默认配置和拦截器的属性: defaults/interceptors
  2. 不同:
    (1) 默认配置很可能不一样
    (2) instance没有axios后面添加的一些方法: create()/CancelToken()/all()

axios运行的整体流程?

  1. 整体流程:
    request(config) ==> dispatchRequest(config) ==> xhrAdapter(config)
  2. request(config):
    将请求拦截器 / dispatchRequest() / 响应拦截器 通过promise链串连起来, 返回promise
  3. dispatchRequest(config):
    转换请求数据 ===> 调用xhrAdapter()发请求 ===> 请求返回后转换响应数据. 返回promise
  4. xhrAdapter(config):
    创建XHR对象, 根据config进行相应设置, 发送特定请求, 并接收响应数据, 返回promise

axios的请求/响应拦截器是什么?

  1. 请求拦截器:

    在真正发送请求前执行的回调函数

    可以对请求进行检查或配置进行特定处理

    成功的回调函数, 传递的默认是config(也必须是)

    失败的回调函数, 传递的默认是error

  2. 响应拦截器

    在请求得到响应后执行的回调函数

    可以对响应数据进行特定处理

    成功的回调函数, 传递的默认是response

    失败的回调函数, 传递的默认是error

axios的请求/响应数据转换器是什么?

  1. 请求转换器: 对请求头和请求体数据进行特定处理的函数
javascript 复制代码
if (utils.isObject(data)) {
   setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
   return JSON.stringify(data);
}
  1. 响应转换器: 将响应体json字符串解析为js对象或数组的函数
javascript 复制代码
response.data = JSON.parse(response.data)

response的整体结构

javascript 复制代码
{
        data,
        status,
        statusText,
        headers,
        config,
        request
  }

error的整体结构

javascript 复制代码
{
       message,
       response,
request,
 }

如何取消未完成的请求?

  1. 当配置了cancelToken对象时, 保存cancel函数
    (1) 创建一个用于将来中断请求的cancelPromise
    (2) 并定义了一个用于取消请求的cancel函数
    (3) 将cancel函数传递出来
  2. 调用cancel()取消请求
    (1) 执行cacel函数, 传入错误信息message
    (2) 内部会让cancelPromise变为成功, 且成功的值为一个Cancel对象
    (3) 在cancelPromise的成功回调中中断请求, 并让发请求的proimse失败, 失败的reason为Cancel对象

Axios二次封装

功能点

  1. 统一进行请求配置: 基础路径/超时时间等
  2. 请求过程中loading提示
  3. 请求可能需要携带token数据
  4. 请求成功的value不再是response, 而是response.data
  5. 请求失败/出错统一进行处理, 每个请求可以不用单独处理

编码实现与测试

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Axios二次封装</title>
  <link rel="stylesheet" href="https://cdn.bootcss.com/nprogress/0.2.0/nprogress.css">
</head>
<body>

<div>
  <button onclick="getUsers()">获取用户列表</button>
  <button onclick="getRepos()">获取仓库列表</button>
</div>
  
  <!-- 
    测试接口1: https://api.github.com/search/repositories?q=v&sort=stars
    测试接口1: https://api.github.com/search/users?q=v
  -->
  <!--
   1). 统一进行请求配置: 基础路径/超时时间等
   2). 请求过程中loading提示
   3). 请求可能需要携带token数据
   4). 请求成功的value不再是response, 而是response.data
   5). 请求失败/出错统一进行处理, 每个请求可以不用单独处理
  -->

  <script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
  <script src="https://cdn.bootcss.com/nprogress/0.2.0/nprogress.js"></script>
  <script>
    const instance = axios.create({
      baseURL: 'https://api.github.com',
      timeout: 15000
    })

    instance.interceptors.request.use(config => {
      NProgress.start()
      // 从local中读取前面保存的token数据
      const token = localStorage.getItem('token_key') || 'xxxxx'
      if (token) {
        config.headers['token'] = token  // 请求头的名称为后台接口指定
      }

      return config
    })

    instance.interceptors.response.use(
      response => {
        NProgress.done()
        return response.data
      },
      error => {
        NProgress.done()
        alert('请求出错了', error)
        return error
      }
    )
  </script>

  <script>
    function getUsers () {
      instance.get('/search/users', {
        params: {
          q: 'v'
        }
      }).then(result => {
        console.table(result.items)
      })
    }

    function getRepos () {
      instance.get('/search/repositories', {
        params: {
          q: 'v',
          sort: 'stars'
        }
      }).then(result => {
        console.table(result.items)
      })
    }
  </script>
</body>
</html>
相关推荐
种时光的人7 分钟前
多线程出bug不知道如何调试?java线程几种常见状态
java·python·bug
小尹哥-程序员9 分钟前
springboot2.X创建maven多模块工程
java·maven
web安全工具库11 分钟前
Python内存管理之隔代回收机制详解
java·jvm·算法
大学生亨亨17 分钟前
蓝桥杯之递归
java·笔记·算法·蓝桥杯
不辉放弃19 分钟前
MySQL存储过程
java·数据库·sql
Freak嵌入式23 分钟前
一文速通Python并行计算:09 Python多进程编程-进程之间的数据同步-基于互斥锁、递归锁、信号量、条件变量、事件和屏障
开发语言·python·多线程·并发·并行
T糖锅G27 分钟前
小白自学python第一天
开发语言·python
学Java的小半37 分钟前
用键盘实现控制小球上下移动——java的事件控制
java·开发语言·算法·intellij-idea·gui·事件监听
阿桂天山1 小时前
实现批量图片文字识别(python+flask+EasyOCR)
开发语言·python·flask
天天进步20151 小时前
Python跨平台桌面应用程序开发
开发语言·python