JavaScript 实现页面刷新时发送停止请求的 sendBeacon 方案

作者:函数茶馆

时间:2026-10-31

浏览:549

本文探讨在页面刷新或关闭标签页时成功发送停止请求的技术方案。针对 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 中实现页面刷新或关闭时成功发送停止请求的介绍已完成。如需了解更多相关内容,欢迎查阅本站过往文章或继续浏览后续系列教程,感谢大家的支持。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章