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>
相关推荐
郝YH是人间理想42 分钟前
Python面向对象
开发语言·python·面向对象
大刀爱敲代码2 小时前
基础算法01——二分查找(Binary Search)
java·算法
大土豆的bug记录3 小时前
鸿蒙进行视频上传,使用 request.uploadFile方法
开发语言·前端·华为·arkts·鸿蒙·arkui
maybe02093 小时前
前端表格数据导出Excel文件方法,列自适应宽度、增加合计、自定义文件名称
前端·javascript·excel·js·大前端
追风少年1554 小时前
常见中间件漏洞之一 ----【Tomcat】
java·中间件·tomcat
yang_love10114 小时前
Spring Boot 中的 @ConditionalOnBean 注解详解
java·spring boot·后端
hhw1991125 小时前
c#知识点补充3
开发语言·c#
Antonio9155 小时前
【Q&A】观察者模式在QT有哪些应用?
开发语言·qt·观察者模式
Pandaconda5 小时前
【后端开发面试题】每日 3 题(二十)
开发语言·分布式·后端·面试·消息队列·熔断·服务限流
郑州吴彦祖7725 小时前
【Java】UDP网络编程:无连接通信到Socket实战
java·网络·udp