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>
相关推荐
二级小助手2 分钟前
二级Web前端选择题高频真题20道与考场避坑笔记
javascript·css3·html5·web前端·计算机二级·二级web·web真题
城管不管14 分钟前
重生——第十次面试之开源中国一面挂
java·linux·开发语言·算法·面试·职场和发展·开源
Java小白笔记18 分钟前
Windows系统免软件命令激活
java·网络·人工智能·windows·ai·ai编程
爱敲键盘的猴子27 分钟前
深入理解 Java HashMap
java·hashmap
霸道流氓气质27 分钟前
Java开发者AI编程常用MCP、Skills、Rules全景汇总
java·开发语言·ai编程
前端小卡拉38 分钟前
用了大半年 AI 编程工具,我才搞懂 Skill 到底是什么
前端·javascript
天涯醉青楼39 分钟前
Spring Boot 接口返回 Bean 时字段名“变形”的深度剖析与解决方案
java
郭邯1 小时前
用 Intl.DateTimeFormat 手写一个时区转换器,顺便聊聊我和 AI 结对编程的日常
前端·javascript
zoujiahui_20181 小时前
Python 包与环境管理工具 uv
开发语言·python·uv
步行cgn1 小时前
MyBatis 高级映射与延迟加载完全指南
java·tomcat·mybatis