Axios库相关

axios 的理解和使用

axios 是什么

  1. 前端最流行的 ajax 请求库
  2. react/vue 官方都推荐使用 axios 发 ajax 请求

axios 特点:

  1. 基于 xhr + promise 的异步 ajax 请求库
  2. 浏览器端/node 端都可以使用
  3. 支持请求/响应拦截器
  4. 支持请求取消
  5. 请求/响应数据转换
  6. 批量发送多个请求

axios 常用语法

axios(config): 通用/最本质的发任意类型请求的方式
axios(url[, config]):可以只指定 url 发 get 请求
axios.request(config):等同于 axios(config)
axios.get(url[, config]): 发 get 请求
axios.delete(url[, config]): 发 delete 请求
axios.post(url[, data, config]):发 post 请求
axios.put(url[, data, config]):发 put 请求
axios.defaults.xxx: 请求的默认全局配置
axios.interceptors.request.use(): 添加请求拦截器
axios.interceptors.response.use(): 添加响应拦截器
axios.create([config]):创建一个新的 axios(它没有下面的功能)
axios.Cancel(): 用于创建取消请求的错误对象
axios.CancelToken(): 用于创建取消请求的 token 对象
axios.isCancel():是否是一个取消请求的错误
axios.all(promises): 用于批量执行多个异步请求
axios.spread():用来指定接收所有成功数据的回调函数的方法

axios的基本使用

JSON-Server 安装

在后台还没给接口之前,使用JSON-Server搭建一台JSON服务器,将接口要返回的数据放在json文件里面。然后请求这些数据,这样我们可以先做一些东西,等后台接口好了之后直接替换就可以了,不必一直傻傻的等后端的接口。

  • 安装json-server
    终端中执行:npm install -g json-server
  • 运行服务器
    终端中执行:json-server --watch db.json(报错:开头加npx)

实例:

  1. db.json文件
{
  "posts": [
    {
      "id": 1,
      "title": "json-server",
      "author": "typicode"
    }
  ],
  "comments": [
    {
      "id": 1,
      "body": "some comment",
      "posId": 1
    }
  ],
  "profile": {
    "name": "typicode"
  }
}
  1. html文件
<body>
    <div class="container">
        <h2 class="page-header">基本使用</h2>
        <button class="btn btn-primary"> 发送GET请求 </button>
        <button class="btn btn-warning"> 发送POST请求 </button>
        <button class="btn btn-success"> 发送 PUT 请求 </button>
        <button class="btn btn-danger"> 发送 DELETE 请求 </button>
    </div>
    <script>
        //    获取按钮
        const btn = document.querySelectorAll("button");
        // 第一个绑定事件
        btn[0].onclick = function () {  //点击读取id为1的文章
            // 发送AJAX请求
            axios({
                // 请求类型
                method: "GET",

                url: 'http://localhost:3000/posts/1', //get请求需要加id

            }).then(response => {
                console.log(response);
            })
        };
        btn[1].onclick = function () {  // 点击增加文章
            // 发送AJAX请求
            axios({
                // 请求类型
                method: "POST",

                url: 'http://localhost:3000/posts', //post请求不需要加id
                // 设置请求体
                data: {
                    title: "今天天气很好!",
                    auther: "张三"
                }
            }).then(response => {
                console.log(response);
            })
        };
        btn[2].onclick = function () {  // 点击修改id为2文章的作者
            // 发送AJAX请求
            axios({
                // 请求类型
                method: "PUT",

                url: 'http://localhost:3000/posts/2', //put请求需要加id
                // 设置请求体
                data: {
                    title: "今天天气很好!",
                    auther: "李四"
                }
            }).then(response => {
                console.log(response);
            })
        };
        btn[3].onclick = function () {  // 点击删除id为2的文章
            // 发送AJAX请求
            axios({
                // 请求类型
                method: "DELETE",

                url: 'http://localhost:3000/posts/2', //delete请求需要加id
                
            }).then(response => {
                console.log(response);
            })
        }
    </script>
</body>

axios.create(config)

  1. 根据指定配置创建一个新的 axios, 也就就每个新 axios 都有自己的配置
  2. 新 axios 只是没有取消请求和批量发请求的方法, 其它所有语法都是一致的
  3. 为什么要设计这个语法?
    (1) 需求: 项目中有部分接口需要的配置与另一部分接口需要的配置不太一
    样, 如何处理
    (2) 解决: 创建 2 个新 axios, 每个都有自己特有的配置, 分别应用到不同要
    求的接口请求中

拦截器

实例:

<body>
    <script>
        // Promise
        // 设置请求拦截器  config 配置对象
        axios.interceptors.request.use(function (config) {
            console.log('请求拦截器 成功 - 1号');
            //修改 config 中的参数
            config.params = {a:100};

            return config;
        }, function (error) {
            console.log('请求拦截器 失败 - 1号');
            return Promise.reject(error);
        });

        axios.interceptors.request.use(function (config) {
            console.log('请求拦截器 成功 - 2号');
            //修改 config 中的参数
            config.timeout = 2000;
            return config;
        }, function (error) {
            console.log('请求拦截器 失败 - 2号');
            return Promise.reject(error);
        });

        // 设置响应拦截器
        axios.interceptors.response.use(function (response) {
            console.log('响应拦截器 成功 1号');
            return response.data;
            // return response;
        }, function (error) {
            console.log('响应拦截器 失败 1号')
            return Promise.reject(error);
        });

        axios.interceptors.response.use(function (response) {
            console.log('响应拦截器 成功 2号')
            return response;
        }, function (error) {
            console.log('响应拦截器 失败 2号')
            return Promise.reject(error);
        });

        //发送请求
        axios({
            method: 'GET',
            url: 'http://localhost:3000/posts'
        }).then(response => {
            console.log('自定义回调处理成功的结果');
            console.log(response);
        });
    </script>   
</body>

拦截器函数/ajax 请求/请求的回调函数的调用顺序

  1. 说明: 调用 axios()并不是立即发送 ajax 请求, 而是需要经历一个较长的流程
  2. 流程: 请求拦截器2 => 请求拦截器1 => 发ajax请求 => 响应拦截器1 => 响
    应拦截器 2 => 请求的回调
  3. 注意: 此流程是通过 promise 串连起来的, 请求拦截器传递的是 config, 响应
    拦截器传递的是 response

取消请求

  1. 基本流程
    配置 cancelToken 对象
    缓存用于取消请求的 cancel 函数
    在后面特定时机调用 cancel 函数取消请求
    在错误回调中判断如果 error 是 cancel, 做相应处理
  2. 实现功能
    点击按钮, 取消某个正在请求中的请求
  3. 在请求一个接口前, 取消前面一个未完成的请求

实例:

<body>
    <div class="container">
        <h2 class="page-header">axios取消请求</h2>
        <button class="btn btn-primary"> 发送请求 </button>
        <button class="btn btn-warning" > 取消请求 </button>
    </div>
    <script>
        //获取按钮
        const btns = document.querySelectorAll('button');
        //2.声明全局变量
        let cancel = null;
        //发送请求
        btns[0].onclick = function(){
            //检测上一次的请求是否已经完成
            if(cancel !== null){
                //取消上一次的请求
                cancel();
            }
            axios({
                method: 'GET',
                url: 'http://localhost:3000/posts',
                //1. 添加配置对象的属性
                cancelToken: new axios.CancelToken(function(c){
                    //3. 将 c 的值赋值给 cancel
                    cancel = c;
                })
            }).then(response => {
                console.log(response);
                //将 cancel 的值初始化
                cancel = null;
            })
        }

        //绑定第二个事件取消请求
        btns[1].onclick = function(){
            cancel();
        }
    </script>   
</body>

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. 请求拦截器:

(1)在真正发送请求前执行的回调函数
(2)可以对请求进行检查或配置进行特定处理
(3)成功的回调函数, 传递的默认是 config(也必须是)
(4)失败的回调函数, 传递的默认是 error

  1. 响应拦截器

(1)在请求得到响应后执行的回调函数
(2)可以对响应数据进行特定处理
(3)成功的回调函数, 传递的默认是 response
(4)失败的回调函数, 传递的默认是 error

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

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

response 的整体结构

{
 data,
 status,
 statusText,
 headers,
 config,
 request
 }

error 的整体结构

{
 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 对象
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值