前端如何中断请求 ( axios、原生 ajax、fetch)
使用场景
在前端开发中,我们经常需要中断请求来优化性能或处理特定的业务需求。以下是一些常见的使用场景:
比如
- 重复请求:当页面中多个组件并发调用同一个接口时,在第一个请求返回后,我们可能需要中断其他组件对该接口的调用,以避免重复请求和冗余数据。这在组件高度复用、不依赖公共 API 的情况下特别有用。
- 竞态请求:当页面定时轮询发起请求时,如果上一个请求的响应速度比下一个请求慢,会导致数据错乱。中断较慢的请求可以确保只处理最新的数据,避免竞态条件。
- 无效请求:在单页应用中,当组件加载过慢,路由跳转后可能会导致组件卸载,但请求仍在进行中。如果接口返回错误,错误提示可能会在其他页面弹出。中断无效请求可以避免不必要的错误提示。
- 大文件上传暂停与恢复:在实现大文件上传功能时,用户可能会需要暂停和恢复上传过程。中断请求可以实现暂停功能,并在需要时重新发起请求以实现恢复上传。
除了以上提到的场景,还有许多其他情况需要中断请求以减少对服务器的无效请求。
下面介绍几种终止请求的方案
原生ajax终止请求
abort() 方法
XMLHttpRequest.abort() 方法用于终止 XMLHttpRequest 对象的请求。调用该方法后,如果请求正在处理中,则会中止该请求;如果请求已经完成(即已经接收到完整的响应),则不会执行任何操作。同时,调用该方法会触发 XMLHttpRequest 对象的 abort 事件,我们可以在事件处理函数中执行后续的逻辑代码,如清除请求相关的数据等。
当一个请求被终止后,它的 readyState 属性将变为 0,status 属性也会变为 0。
案例代码:
// 创建XMLHttpRequest对象
const xhr = new XMLHttpRequest();
// 请求地址
const url = "https://developer.mozilla.org/";
// 初始化请求
xhr.open('GET', url, true);
// 发送请求
xhr.send();
// 监听取消请求
xhr.addEventListener('abort', function () {console.log('请求被abort()取消了');
});
// 定时器模拟取消请求
setTimeout(() => {// 取消请求xhr.abort();// 取消请求之后的状态statusconsole.log('abort()之后的xhr.status---', xhr.status);// 取消请求之后的状态readyStateconsole.log('abort()之后的xhr.readyState---', xhr.readyState);
}, 100);
fetch 终止请求
使用 AbortController 可以中断 Fetch 请求。AbortController 是一个新的 Web 标准,用于中止 DOM 请求和 Fetch 请求。在执行 Fetch 请求时,可以通过 AbortController 创建一个信号对象 signal,并将 signal 作为配置选项传递给 fetch() 方法,这样就可以通过调用 AbortController 对象的 abort() 方法来中止请求。
案例代码:
const controller = new AbortController();
const { signal } = controller;
// 请求地址
const url = "https://developer.mozilla.org/";
fetch(url, { signal }).then(response => response.json()).then(data => console.log(data)).catch(error => console.error(error));// 中止 fetch 请求
controller.abort();
axios 终止请求
AbortController(新版本)
从 axios 的 0.22.0 版本开始,推荐使用浏览器原生的 AbortController 来终止请求。当使用该方法终止请求时,如果请求正在处理中,则会中止该请求;如果请求已经完成(即已经接收到完整的响应),则不会执行任何操作。
我们可以通过两种方式来监听终止请求的操作并进行后续处理:
- 使用 AbortController 提供的 onabort 事件,通过监听该事件并绑定事件处理函数,在函数中执行后续处理逻辑。
- 使用 try…catch,终止请求后会触发 catch,可以在 catch 中进行后续处理。如果同时使用 onabort 事件和 try…catch,则会先触发 onabort 事件,再触发 try…catch。
案例代码:
// 以vue项目中使用axios为例
// 创建请求控制器
this.controller = new AbortController();
console.log("初始声明的请求控制器------", this.controller);const url = "https://developer.mozilla.org/";
// 第一种方法:绑定事件处理程序
this.controller.signal.addEventListener("abort", () => {console.log("请求已终止,触发了onabort事件");// 进行后续处理
});// 第二种方法:try...catch
try {// 发送文件上传请求const res = await this.$axios.post(url, {}, {timeout: 0, // 设置超时时间为 0/null 表示永不超时signal: this.controller.signal, // 绑定取消请求的信号量});
} catch (error) {console.log("终止请求时catch的error---", error);// 判断是否为取消上传if (error.message == "canceled"){// 进行后续处理};
}// 终止请求
this.controller.abort();
console.log("终止请求后的请求控制器------", this.controller);
需要注意的是,每个 AbortController 可以同时取消多个请求,但只能取消请求一次。终止请求后,该请求的 signal.aborted 属性会从 false 变为 true。目前,暂无方法可以将其恢复为 false。如果后续请求仍然绑定了该请求控制器,那么后续请求都会被提前终止,不会被发送。
如果想要在终止请求后不影响后续请求的正常发送,并且后续请求也能够被终止,需要在每次发送请求之前都通过构造函数创建一个新的 AbortController,并将每次请求绑定到新的 AbortController 上,以确保多次请求之间不会相互干扰。
CancelToken( axios 旧版本)
在 axios 的 0.22.0 版本之前,可以使用取消令牌(CancelToken)来中止请求。不过,从 0.22.0 版本开始,该 API 已被弃用,不再建议使用。当使用该方法终止请求时,如果请求正在处理中,则会中止该请求;如果请求已经完成(即已经接收到完整的响应),则不会执行任何操作。
该方法只能通过try…catch来监听取消请求操作,终止请求之后,会触发catch,在catch中进行后续处理。而且该方法在取消请求时,可以通过参数自定义catch的error中的message内容。
案例代码:
// 以vue项目中使用axios为例// 这个地方需要导入原生的axios 最好不要使用二次封装后的axios
import axios from "axios";
const url = "https://developer.mozilla.org/";
// 创建请求令牌
this.source = axios.CancelToken.source();
console.log("初始声明的请求令牌---", this.source);// 第二种方法:try...catch
try {// 发送文件上传请求const res = await this.$axios.post(url, {}, {timeout: 0, // 设置超时时间为 0/null 表示永不超时cancelToken: this.source.token, // 绑定取消请求的令牌});
} catch (error) {console.log("终止请求时catch的error---", error);// 判断是否为取消上传if (error.message == "自定义取消请求的message"){// 进行后续处理};
}// 终止请求
this.source.cancel("自定义取消请求的message");
console.log("取消请求后的请求令牌---", this.source);
注意:该方法与AbortController相同,都可以同时取消多个请求,但是只能取消请求一次,一个CancelToken在终止过请求之后,如果后续请求还是绑定该请求令牌,则后续请求都会被提前终止,不会被发出。
同理,如果我们想要在终止请求之后,不影响后续请求的正常发出,且后续请求也是可以被终止的,那么需要在每次发出请求之前,都创建一个新的的 CancelToken,每次请求绑定的都是新的CancelToken,这样才能做到多次请求之间不干扰。
相关文章:
前端如何中断请求 ( axios、原生 ajax、fetch)
使用场景 在前端开发中,我们经常需要中断请求来优化性能或处理特定的业务需求。以下是一些常见的使用场景: 比如 重复请求:当页面中多个组件并发调用同一个接口时,在第一个请求返回后,我们可能需要中断其他组件对该接…...
CSS实现一些小功能
1.信封边框的实现 1.1 使用背景渐变 <!DOCTYPE html><html><head><meta charset"UTF-8"><title></title><style type"text/css">.uu {width: 200px;height: 70px;padding:1em;border: 1em solid transparent;…...
Ubuntu安装nfs服务步骤
Ubuntu安装nfs服务步骤 一、NFS? NFS:网络文件系统(Network File system File)缩写,可通过网络让不同的机器,不同操作系统之间可以彼此共享文件和目录。 二、安装 1.安装nfs服务器命令:sudo…...
android开发:子线程更新UI界面
多线程操作经常希望在子线程更新界面,这样方便调试,但是,但是经常这样做程序就不对劲了,为什么呢?因为为了保证界面流畅,不允许在非UI线程直接操作界面,只能通过一些专门途径进行。另外…...
P9242 [蓝桥杯 2023 省 B] 接龙数列(dp+最长接龙序列+分类)
1. 计算0~9为结尾的最长子串长度 2. 对于每个数字,比较其开头可连接子串长度1 与 原来以其末位为末尾的子串长度 3. 更新以其末位为末尾的子串长度 #include<iostream> #include<string.h>using namespace std;// 相当于记录…...
网络运维与网络安全 学习笔记2023.11.29
网络运维与网络安全 学习笔记 第三十天 今日更新太晚啦!!! 主要是今天工作时挨了一天骂,服了,下次记得骂的轻一点!!! (要不是为了那点微薄的薪资,谁愿意听你…...
Java实现通过经纬度求两个任意地点在球面上的距离
我们在实际开发中会获取对应的经纬度,可以使用ES大数据搜索引擎进行计算对应区域的数据,那我们在如何根据两个经纬度获取对应的球面距离,就是在地球上从一个地点到另一个地点的直线距离 工具类如下: public class GeoUtils {// 地球半径&am…...
vscode使用插件KoroFileHeader添加注释
一、简介 KoroFileHeader 是一款用于在 VSCode 中用于生成文件头部注释和函数注释的插件,支持所有主流语言,功能强大,灵活方便,文档齐全。 VSCode 安装 KoroFileHeader 好插件,就可以直接使用。 "fileheader.cu…...
NSAttributedString设置折行方式NSLineBreakByTruncatingTail,计算高度出错,高度返回异常。
iOS13上,NSAttributedString设置折行方式NSLineBreakByTruncatingTail,计算高度出错,只返回一行的高度。 NSMutableParagraphStyle *style [[NSMutableParagraphStyle alloc]init]; style.hyphenationFactor 1; // 设置每行的最后单词是…...
YOLOv8改进 | 2023 | DWRSeg扩张式残差助力小目标检测 (附修改后的C2f+Bottleneck)
论文地址:官方论文地址 代码地址:该代码目前还未开源,我根据论文内容进行了复现内容在文章末尾。 一、本文介绍 本文内容给大家带来的DWRSeg中的DWR模块来改进YOLOv8中的C2f和Bottleneck模块,主要针对的是小目标检测,…...
ssm+vue的物资物流系统的设计与实现(有报告)。Javaee项目,ssm vue前后端分离项目。
演示视频: ssmvue的物资物流系统的设计与实现(有报告)。Javaee项目,ssm vue前后端分离项目。 项目介绍: 采用M(model)V(view)C(controller)三层体…...
纵行科技获评“汽车物流行业优秀技术装备供应商”
近日,由中国物流与采购联合会主办,中物联汽车物流分会承办的“2023年全国汽车物流行业年会”在湖北十堰盛大召开。本次年会集合了汽车整车、零部件、售后备件、进出口物流企业和物流装备技术企业、科研机构及院校等,分享汽车物流行业现状、相…...
Chrome和chromedriver版本不匹配导致的UI自动化测试无法运行的问题
今天,遇到一个小问题,本来跑的好好UI自动化测试脚本突然不好使了,期初怀疑是页面元素有调整导致脚本出现异常无法正常执行,经排查后发现近期页面没有任何调整。 这下头大了,啥也没改,怎么好好的脚本不能跑…...
[go 面试] 深入理解进程、线程和协程的概念及区别
关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力! 在操作系统中,我们经常听到进程、线程和协程这些概念,它们都是用来描述执行单元的。接下来,我…...
人工智能即将彻底改变你使用计算机的方式
文章目录 每个人的私人助理“Clippy 是一个机器人,而不是特工。”卫生保健“一半需要心理健康护理的美国退伍军人没有得到治疗。”教育生产率娱乐和购物科技行业的冲击波技术挑战隐私和其他重大问题 今天我仍然像保罗艾伦和我创办微软时一样热爱软件。但是ÿ…...
工艺系统所管理数字化实践
摘要 本文介绍了上海核工程设计研究院在数字化转型方面的实践,包括业务数字化和管理数字化两个方面。业务数字化方面,该院通过开发小工具改进工作流程。管理数字化方面,该院采用零代码平台集中管理管道力学信息相关模型和数据,并…...
VsCode学习
一、在VsCode 上编写第一个C语言 在VsCode上写代码都是先打开文件夹,这样也方便管理代码和编译器产生的可执行程序,VsCode生成的配置文件等。 1.1打开文件夹 写代码前,首先创立一个文件夹存储以后我们写的VsCode代码,便于管理。…...
Javaweb之Vue组件库Element案例的详细解析
4.4 案例 4.4.1 案例需求 参考 资料/页面原型/tlias智能学习辅助系统/首页.html 文件,浏览器打开,点击页面中的左侧栏的员工管理,如下所示: 需求说明: 制作类似格式的页面 即上面是标题,左侧栏是导航&…...
Bert-VITS2本地部署遇到的错误
关于Bert-VITS2本地部署遇到的错误 1、在下载python中相关依赖时报错 building ‘hdbscan._hdbscan_tree’ extension error: Microsoft Visual C 14.0 or greater is required. Get it with “Microsoft C Build Tools”: https://visualstudio.microsoft.com/visual-cpp-bu…...
【Ambari】HDFS基于Ambari的常规运维
🦄 个人主页——🎐开着拖拉机回家_大数据运维-CSDN博客 🎐✨🍁 🪁🍁🪁🍁🪁🍁🪁🍁 🪁🍁🪁…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
