axios.create、拦截器、取消请求

2023-05-16

axios.create(config)

  1. 根据指定配置创建一个新的 axios, 也就就每个新 axios 都有自己的配置
  2. 新 axios 只是没有取消请求和批量发请求的方法, 其它所有语法都是一致的
  3. 为什么要设计这个语法?
    (1) 需求: 项目中有部分接口需要的配置与另一部分接口需要的配置不太一
    样, 如何处理
    (2) 解决: 创建 2 个新 axios, 每个都有自己特有的配置, 分别应用到不同要
    求的接口请求中
<!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.create()</title>
</head>
<body>
  <!-- 
  1). axios.create(config)
    a. 根据指定配置创建一个新的axios, 也就就每个新axios都有自己的配置
    b. 新axios只是没有取消请求和批量发请求的方法, 其它所有语法都是一致的
    c. 为什么要设计这个语法?
      需求: 项目中有部分接口需要的配置与另一部分接口需要的配置不太一样, 如何处理
      解决: 创建2个新axios, 每个都有自己特有的配置, 分别应用到不同要求的接口请求中
  -->
  <script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
  <script>
    axios.defaults.baseURL = 'http://localhost:3000'

    // 使用axios发请求
    axios({
      url: '/posts' // 请求3000
    })

    // axios({
    //   url: '/xxx' // 请求4000
    // })

    const instance = axios.create({
      baseURL: 'http://localhost:4000'
    })

    // 使用instance发请求
    // instance({
    //   url: '/xxx'  // 请求4000
    // })
    instance.get('/xxx')
  </script>
</body>
</html>

拦截器函数

对request拦截器采用unshift(堆栈)
request.hanlders.forEach(item=>chains.unshift(item))
对response拦截器采用push(队列)
response.hanlders.forEach(item=>chains.push(item))

<!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>
</head>
<body>
  
  <script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
  <script>
    /* 
    requestInterceptors: [{fulfilled1(){}, rejected1(){}}, {fulfilled2(){}, rejected2(){}}]
    responseInterceptors: [{fulfilled11(){}, rejected11(){}}, {fulfilled22(){}, rejected22(){}}]
    chain: [
      fulfilled2, rejected2, fulfilled1, rejected1, 
      dispatchReqeust, undefined, 
      fulfilled11, rejected11, fulfilled22, rejected22
    
    ]
    promise链回调: config 
                  => (fulfilled2, rejected2) => (fulfilled1, rejected1)   // 请求拦截器处理
                  => (dispatchReqeust, undefined) // 发请求
                  => (fulfilled11, rejected11) => (fulfilled22, rejected22) // 响应拦截器处理
                  => (onResolved, onRejected) // axios发请求回调处理
    */

    // 添加请求拦截器(回调函数)
    axios.interceptors.request.use(
      config => {
        console.log('request interceptor1 onResolved()')
        return config
      },
      error => {
        console.log('request interceptor1 onRejected()')
        return Promise.reject(error);
      }
    )
    axios.interceptors.request.use(
      config => {
        console.log('request interceptor2 onResolved()')
        return config
      },
      error => {
        console.log('request interceptor2 onRejected()')
        return Promise.reject(error);
      }
    )
    // 添加响应拦截器
    axios.interceptors.response.use(
      response => {
        console.log('response interceptor1 onResolved()')
        return response
      },
      function (error) {
        console.log('response interceptor1 onRejected()')
        return Promise.reject(error);
      }
    )
    axios.interceptors.response.use(
      response => {
        console.log('response interceptor2 onResolved()')
        return response
      },
      function (error) {
        console.log('response interceptor2 onRejected()')
        return Promise.reject(error);
      }
    )

    axios.get('http://localhost:3000/posts')
      .then(response => {
        console.log('data', response.data)
      })
      .catch(error => {
        console.log('error', error.message)
      })

    /* axios.get('http://localhost:/posts2')
      .then(response => {
        console.log('data', response.data)
      })
      .catch(error => {
        console.log('error', error.message)
      }) 
    */
  </script>
</body>
</html>
  1. 说明: 调用 axios()并不是立即发送 ajax 请求, 而是需要经历一个较长的流程
  2. 流程: 请求拦截器2 => 请求拦截器1 => 发ajax请求 => 响应拦截器1 => 响
    应拦截器 2 => 请求的回调
  3. 注意: 此流程是通过 promise 串连起来的, 请求拦截器传递的是 config, 响应
    拦截器传递的是 response

取消请求

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

基本代码:

<!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>取消请求</title>
</head>
<body>
  <button onclick="getProducts1()">获取商品列表1</button><br>
  <button onclick="getProducts2()">获取商品列表2</button><br>
  <button onclick="cancelReq()">取消请求</button><br>

  <script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
  <script>
    let cancel  // 用于保存取消请求的函数
    function getProducts1() {
      axios({
        url: 'http://localhost:4000/products1',
        cancelToken: new axios.CancelToken((c) => { // c是用于取消当前请求的函数
          // 保存取消函数, 用于之后可能需要取消当前请求
          cancel = c
        })
      }).then(
        response => {
          cancel = null
          console.log('请求1成功了', response.data)
        },
        error => {
          cancel = null
          console.log('请求1失败了', error.message, error)
        }
      )
    }

    function getProducts2() {
      axios({
        url: 'http://localhost:4000/products2'
      }).then(
        response => {
          console.log('请求2成功了', response.data)
        },
        error => {
          cancel = null
          console.log('请求2失败了', error.message)
        }
      )
    }

    function cancelReq() {
      // alert('取消请求')
      // 执行取消请求的函数
      if (typeof cancel === 'function') {
        cancel('强制取消请求')
      } else {
        console.log('没有可取消的请求')
      }
    }
  </script>
</body>
</html>

在请求一个接口前, 取消前面一个未完成的请求:

 function getProducts1() {
      // 在准备发请求前, 取消未完成的请求
      if (typeof cancel==='function') {
        cancel('取消请求')
      }
      axios({
        url: 'http://localhost:4000/products1',
        cancelToken: new axios.CancelToken((c) => { // c是用于取消当前请求的函数
          // 保存取消函数, 用于之后可能需要取消当前请求
          cancel = c
        })
      }).then(
        response => {
          cancel = null
          console.log('请求1成功了', response.data)
        },
        error => {
          if (axios.isCancel(error)) {
            // cancel = null
            // 若不用这个,如果点三次第一个函数,会导致后面的第2个不能被取消,
            // 因为第一个函数的error回调函数把cancel=null,此时正在执行第二个函数,
            // 最后导致点击第三个函数时,判断的cancel=null,使得不能取消掉之前第二个函数
            console.log('请求1取消的错误', error.message)
          } else { // 请求出错了
            cancel = null
            console.log('请求1失败了', error.message)
          }
        }
      )
    }

使用拦截器优化代码

<!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>取消请求</title>
</head>
<body>
  <button onclick="getProducts1()">获取商品列表1</button><br>
  <button onclick="getProducts2()">获取商品列表2</button><br>
  <button onclick="cancelReq()">取消请求</button><br>

  <script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
  <script>

    // 添加请求拦截器
    axios.interceptors.request.use((config) => {
      // 在准备发请求前, 取消未完成的请求
      if (typeof cancel==='function') {
          cancel('取消请求')
      }
      // 添加一个cancelToken的配置
      config.cancelToken = new axios.CancelToken((c) => { // c是用于取消当前请求的函数
        // 保存取消函数, 用于之后可能需要取消当前请求
        cancel = c
      })

      return config
    })

    // 添加响应拦截器
    axios.interceptors.response.use(
      response => {
        cancel = null
        return response
      },
      error => {
        if (axios.isCancel(error)) {// 取消请求的错误
          // cancel = null
          console.log('请求取消的错误', error.message) // 做相应处理
          // 中断promise链接
          return new Promise(() => {})
        } else { // 请求出错了
          cancel = null
          // 将错误向下传递
          // throw error
          return Promise.reject(error)
        }
      }
    )


    let cancel  // 用于保存取消请求的函数
    function getProducts1() {
      axios({
        url: 'http://localhost:4000/products1',
      }).then(
        response => {
          console.log('请求1成功了', response.data)
        },
        error => {// 只用处理请求失败的情况, 取消请求的错误的不用
          console.log('请求1失败了', error.message)          
        }
      )
    }

    function getProducts2() {

      axios({
        url: 'http://localhost:4000/products2',
      }).then(
        response => {
          console.log('请求2成功了', response.data)
        },
        error => {
          console.log('请求2失败了', error.message)
        }
      )
    }

    function cancelReq() {
      // alert('取消请求')
      // 执行取消请求的函数
      if (typeof cancel === 'function') {
        cancel('强制取消请求')
      } else {
        console.log('没有可取消的请求')
      }
    }
  </script>
</body>
</html>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

axios.create、拦截器、取消请求 的相关文章

  • 树莓派4B安装Ros 2 Foxy踩坑记录

    1 通过树莓派官方提供的写卡工具raspberry pi imager选择Ubuntu 20 04 5 xff08 64 bit xff09 xff0c 因为我打算用一个8G的存储卡安装ros 2 xff0c Ubuntu 22 04的比较
  • 浅谈第三方登录用户表结构设计方案

    国民两大流量入口 xff0c 大家不说也想到了 xff0c 分别是微信和QQ 所以为了方便获取用户来源都对接了微信登录或者QQ登录 xff0c 这一类型的第三方登录入口 今天就以对接微信登录 QQ登录与苹果登录 来说说对第三方用户体系与我方
  • Linux 网络命令

    1 ifconfig查看当前活着的网络接口信息 root 64 localhost ifconfig a 表示显示所有网卡包括没有启动的网卡 root 64 localhost ifconfig ens33 down 关闭网卡 root 6
  • 最新ffmpeg编译和用eclipse进行源码调试

    最近由于项目需要 xff0c 必须修改ffmpeg的源码进行修改才能满足项目的需求 xff0c 但以前我从来没有自己去编译和使用ffmpeg的源代码 xff0c 一直都是用别人编译好了的sdk xff0c 再加上习惯了vs方便的编译环境 x
  • Nginx 基础架构简介

    Nginx Vs Apache 对比项目nginxapache备注进程结构master worker prefork thread mpm 网络结构nio aio lt 61 2 2 BIO gt 61 2 4 BIO NIO 模块处理异步
  • 使用<script setup>报错: ‘defineProps‘ is not defined

    解决方法1 xff1a 在 eslintrc js 的 env 增加配置 env 39 vue setup compiler macros 39 true 新增的配置 刚配置完重新启动开发服务的时候可能会报错 xff1a Environme
  • 毕设文档

    lt 64 page size 21cm 29 7cm margin 2cm P margin bottom 0 21cm gt 电话簿功能需求分析 注 xff1a 这里的号码可以是手机号 xff0c 也可以是家庭号码 一 xff1a 显示
  • Docker系列 利用RSShub搭建个人RSS源 从此万物皆RSS

    转自我的个人博客https blognas hwb0307 com 欢迎关注 xff01 前言 通过Docker系列 安装个人RSS服务TTRSS 手机完美适配的学习 xff0c 我们已经成功地搭建了自己的RSS阅读器 可能也有小伙伴通过U
  • docker swarm init

  • Docker系列 深度使用nextcloud(七) 在nextcloud使用RSS订阅

    转自我的个人博客https blognas hwb0307 com 欢迎关注 xff01 前言 如果你对RSS感兴趣 xff0c 可以到我博客的 学习地图 里查看如何用Docker搭建RSS阅读器和自定义RSS源 最近了解RSS的过程中 x
  • Docker系列 WordPress系列 WP Mail SMTP插件

    转自我的个人博客https blognas hwb0307 com 欢迎关注 xff01 前言 在 Docker系列 WordPress系列 安全插件 一章中 xff0c 我们安装了一些网站安全有关的插件 在本章 xff0c 我再向大家介绍
  • Docker系列 WordPress系列 国服最强博客看板娘没有之一

    转自我的个人博客https blognas hwb0307 com 欢迎关注 xff01 前言 在 Docker系列 WordPress系列 特效 教程中 xff0c 你应该已经学会怎么使用一个CDN看板娘 xff0c 比如 xff1a l
  • Docker系列 通过FRP实现内网穿透

    转自我的个人博客https blognas hwb0307 com 欢迎关注 xff01 前言 有小伙伴提醒 xff0c fatedier frps才是frp官方的Docker镜像 但我看这个官方镜像都没有详细的使用说明 xff0c 所以不
  • 使用FRP进行内网穿透的最佳实践

    转自我的个人博客https blognas hwb0307 com 欢迎关注 xff01 前言 前不久我出过一期 Docker系列 通过FRP实现内网穿透 讲述怎么利用FRP进行内网穿透 不过 xff0c 经过测试 xff0c 很快我发现此
  • Docker系列 Wallabag助力个性化网页RSS化

    转自我的个人博客https blognas hwb0307 com 欢迎关注 xff01 前言 使用RSS阅读已经有一段时间了 xff0c 感觉RSS信息流确实很舒服 xff0c 大大提高了生活和工作效率 在日常工作或学习中 xff0c 经
  • Docker系列 酷炫的服务器性能监测工具netdata

    转自我的个人博客https blognas hwb0307 com 欢迎关注 xff01 前言 此文内容目前处于BETA版本 我之前在 Linux基础 目录管理的个人实践 曾经介绍过一款叫Ward的VPS性能监控应用 xff0c 当时对它的
  • Docker系列 WordPress系列 个人博客的广告展示

    转自我的个人博客https blognas hwb0307 com 欢迎关注 xff01 前言 某些网站访问的时候 xff0c 网页里会有很多广告 有些广告多的 xff0c 阅读体验很差 xff0c 非常恼人 在电脑端浏览网页时 xff0c
  • Docker系列 头脑风暴专用手绘图应用excalidraw

    转自我的个人博客https blognas hwb0307 com 欢迎关注 xff01 前言 前段时间逛Github的时候偶然发现了一个叫excalidraw的应用 xff0c Github Repo有30 8k的Star excalid
  • Docker系列 自建代码托管和版本控制平台Gogs

    转自我的个人博客https blognas hwb0307 com 欢迎关注 xff01 前言 相信大家对Github Gitee这类第三方商业平台不陌生 特别是Github xff0c 来自全世界的大多数优秀开发者都在Github上托管他
  • Ubuntu 虚拟机无法联网(NAT模式下)- 解决方法

    想要在 Ubuntu16 04 虚拟机上安装 git 克隆仓库 xff0c 只需在 Ubuntu 终端输入以下命令即可 xff1a sudo apt get install git 但是我在输入之后并未安装成功 xff0c 反而显示以下结果

随机推荐

  • 一种有效的基于VPS和RSS的科研小白文献阅读策略

    转自我的个人博客https blognas hwb0307 com 欢迎关注 xff01 前言 科研工作人员都有很强的文献阅读的需求 及时了解他人的工作对于开拓研究视野 研究思路是很有帮助的 对于刚刚进入科研领域的新人小白 xff0c 为了
  • Docker系列 WordPress系列 自建随机图API之动态壁纸

    转自我的个人博客https blognas hwb0307 com 欢迎关注 xff01 目录 前言基础随机图apiimg mobile txtmp4 txtindex mobileOnly phpindex annimated php 页
  • Docker系列 WordPress系列 动态对话页面

    转自我的个人博客https blognas hwb0307 com 欢迎关注 xff01 前言 今天咱们又来整点花活了 xff01 应小伙伴sherwin的请求 xff0c 我抽空搞了一个 动态对话 页面 xff0c 界面大致如下 xff1
  • Docker系列 深度使用nextcloud(九) 硬盘挂载

    转自我的个人博客https blognas hwb0307 com xff0c 该文的内容更新仅在个人博客可见 欢迎关注 xff01 前言 基于 Docker系列 搭建个人云盘服务nextcloud xff0c 相信无论是在有 无443端口
  • Docker系列 深度使用nextcloud (十一) 特效

    转自我的博客文章https blognas hwb0307 com linux docker 3203 xff0c 内容更新仅在个人博客可见 欢迎关注 xff01 前言 今天咱又来Nextcloud里玩点花样了 96 作为一个WordPre
  • NAS系列 为什么你需要一台NAS

    转自我的博客文章https blognas hwb0307 com nas 3213 xff0c 内容更新仅在个人博客可见 欢迎关注 xff01 前言 之前无论是写Linux还是Docker的教程 xff0c 都是基于VPS的 如果已经学习
  • NAS系列 硬件选择

    转自我的博客文章https blognas hwb0307 com nas 3224 xff0c 内容更新仅在个人博客可见 欢迎关注 xff01 前言 经过 NAS系列 为什么你需要一台NAS 的简单介绍 xff0c 如果你也决定像我一样组
  • NAS系列 硬件组装

    转自我的博客文章https blognas hwb0307 com nas 3260 xff0c 内容更新仅在个人博客可见 欢迎关注 xff01 前言 之前我在 NAS系列 硬件选择 里讲述了自己为了升级NAS如何选配硬件 本节我大概说一些
  • Docker系列 基于OpenAI API自建ChatGPT

    转自我的博客文章https blognas hwb0307 com linux docker 4201 xff0c 内容更新仅在个人博客可见 欢迎关注 xff01 前言 我用帐号 密码使用chatGPT已经有一段时间 但是 xff0c 我有
  • Thinkpad E431 解决无线网卡无法开启

    Thinkpad E431无线网卡无法开启 现象再现 xff1a Thinkpad E431新机 xff0c 原装win8系统 xff0c 使用win7光盘换为win7系统 xff0c 官方下载驱动程序 xff0c 安装后无线上网正常 点击
  • 华为OD真题-字符串重新排列

    描述 给定一个字符串s xff0c s包括以空格分隔的若干个单词 xff0c 请求s进行如下处理后输出 xff1a 单词内部调整 xff1a 对每个单词字母重新按字典序排序 单词间顺序调整 xff1a 统计每个单词出现的次数 xff0c 并
  • 如何在CSDN博客中所贴的代码进行【代码块】显示

    笔者学习android开发有半年多了 xff0c 而CSDN也陪伴我半年有余 xff0c 在开发全国移动终端参赛项目的时候 xff0c 就在CSDN上看别人的博客 xff0c 解决问题 xff0c 下载好的代码资源研究 xff0c 可谓CS
  • Ubuntu 16.04 安装 高版本远程桌面xrdp+xorg

    Ubuntu 16 04 安装 高版本远程桌面xrdp 43 xorg Ubuntu 16 04提供的官方源里面只能安装0 6 1版本的xrdp xff0c 大概长这个样子 这个版本的远程桌面有很多问题 xff0c 首先是无法在本地电脑和远
  • 2021.04.03-2021.04.04 省选模拟 总结

    地址 Day 1 xff1a https gmoj net senior contest home 3355 Day 2 xff1a https gmoj net senior contest home 3356 总结 两天都考得不好 xf
  • Linux 文件系统扩展属性

    扩展属性 xff08 xattrs xff09 提供了一个机制用来将 键 值 对永久地关联到文件 xff0c 让现有的文件系统得以支持在原始设计中未提供的功能 扩展属性是文件系统不可知论者 xff0c 应用程序可以通过一个标准的接口来操纵他
  • linux内核模块Makefile

    方式一 xff1a 当linux内核驱动模块代码位于内核源码目录树外部时 xff0c 以helloworld模块为例 xff0c Makefile 写法如下 xff1a warning KERNELRELEASE 61 KERNELRELE
  • PHP调用C语言实现接口方法

    一 环境准备 环境 xff1a CentOS Linux release 7 3 1611 Core PHP 5 4 16 安装php 查看php版本 yum install php php devel php v 二 so 动态库封装 r
  • dd if=/dev/zero of=的含义是什么?Linux 下的dd命令使用详解

    xfeff xfeff dd if 61 dev zero of 61 的含义是什么 xff1f Linux 下的dd命令使用详解 转载 xff1a http blog sina com cn s blog 8b5bb24f01016y3o
  • mysql 错 Could not open JDBC Connection for transaction; nested exception is java.sql.SQLExceptio

    运行时报com mysql jdbc exceptions jdbc4 MySQLSyntaxErrorException Unknown character set 39 utf8mb4 39 导致 浏览器报Could not open
  • axios.create、拦截器、取消请求

    axios create config 根据指定配置创建一个新的 axios 也就就每个新 axios 都有自己的配置新 axios 只是没有取消请求和批量发请求的方法 其它所有语法都是一致的为什么要设计这个语法 1 需求 项目中有部分接口