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>
相关推荐
西西学代码17 小时前
Flutter---类
java·开发语言
码农小卡拉17 小时前
Java多线程:CompletableFuture使用详解(超详细)
java·开发语言·spring boot·python·spring·spring cloud
千里马-horse17 小时前
BigInt
开发语言·bigint·napi·addon
Robot侠17 小时前
从 Python 到 Ollama:将微调后的 Llama-3/Qwen 一键导出为 GGUF
开发语言·python·llama·qwen
刺客-Andy17 小时前
JS中级面试题 50道及答案
开发语言·javascript·ecmascript
I'm Jie17 小时前
Gradle 多模块依赖集中管理方案,Version Catalogs 详解(Kotlin DSL)
android·java·spring boot·kotlin·gradle·maven
Java小白笔记17 小时前
BigDecimal用法示例
java·开发语言·spring boot
l1t17 小时前
Python 字符串反转方法
linux·开发语言·python
Eiceblue17 小时前
使用 Python 写入多类型数据至 Excel 文件
开发语言·python·excel
指尖跳动的光17 小时前
防止前端页面重复请求
前端·javascript