JavaScript 实现页面刷新时发送停止请求的 sendBeacon 方案
本文探讨在页面刷新或关闭标签页时成功发送停止请求的技术方案。针对 Vue 生命周期及原生事件在进程终止前请求被取消的问题,对比了同步请求的弊端,最终推荐 navigator.sendBeacon 作为非阻塞且可靠的解决方案,并提供了具体代码实现。
问题背景
近期遇到一个业务需求,要求在用户刷新页面或关闭浏览器标签页的瞬间,触发一个接口以停止当前正在执行的 SQL 任务。
解决方案
首先想到的生命周期函数beforeDestroy,但遗憾的是,beforeDestroy仅在组件销毁时触发。由于关闭标签页时进程会被终止,因此该事件并不会被触发。
随后尝试利用beforeunload和unload事件来捕捉页面刷新或关闭标签页的时机,并在此时调用相应的接口。虽然请求确实发出了,但在页面刷新场景下出现了请求丢失的问题,具体表现如下:

造成这一现象的原因是,页面刷新操作会自动取消当前页面上所有正在进行的异步请求。
针对此问题,一种可行的替代方案是使用原生 XMLHttpRequest,并将其配置为同步请求;或者在使用 jQuery 的 ajax 时,设置$.ajax({ url: "some.php", async: false})参数以实现同步请求。
然而,将请求改为同步方式会带来严重的副作用,即阻塞页面的卸载过程。如果网络请求耗时较长,用户点击刷新或关闭后,界面会一直卡在加载状态,导致极差的用户体验。
经过进一步调研,最终确定了使用 navigator.sendBeacon 方案。该 API 设计用于发送非阻塞请求,不会像同步请求那样阻碍页面的正常卸载流程。
尽管该方案存在一定局限性,即无法在浏览器的network面板中直接观察到请求记录,必须通过抓包工具或后端日志来验证接口是否被调用,但这并不影响核心功能的实现。鉴于其解决了请求被取消和界面卡顿的问题,该方案是可行的。
方案实现代码
_stopSql (sql) {
let formData = new FormData()
formData.append('regionId', regionId)
formData.append('dbName', dbName)
formData.append('sql', sql)
navigator.sendBeacon(`${origin}/stop`, formData)
}
至此,关于如何在 JavaScript 中实现页面刷新或关闭时成功发送停止请求的介绍已完成。如需了解更多相关内容,欢迎查阅本站过往文章或继续浏览后续系列教程,感谢大家的支持。
JS split切割后出现空字符串怎么过滤
2026-11-05 16:00:30
在 React 或 Vue 项目中封装使用 JS 节流防抖
2026-11-05 15:27:29
JavaScript中怎么将带小数的字符串转为整数?
2026-11-05 14:32:38
怎么用JavaScript策略模式重构电商促销计算逻辑?
2026-11-05 14:01:09
JS使用constructor判断数据类型可靠吗
2026-11-05 13:49:41
