Navigator: sendBeacon() 方法
navigator.sendBeacon() 方法 异步地将少量数据通过 HTTP POST 请求发送到 Web 服务器。
它旨在用于将分析数据发送到 Web 服务器,并避免了发送分析数据的传统技术(如使用 XMLHttpRequest)的一些问题。
语法
sendBeacon(url)
sendBeacon(url, data)
参数
url-
将接收数据的 URL。可以是相对路径或绝对路径。
data可选-
包含要发送数据的
ArrayBuffer、TypedArray、DataView、Blob、字符串字面量或对象、FormData或URLSearchParams对象。
返回值
如果 用户代理成功排队等待传输 data,则 sendBeacon() 方法返回 true。否则,它返回 false。
描述
此方法用于分析和诊断代码向服务器发送数据。
发送分析数据时遇到的一个问题是,网站通常希望在用户完成页面交互后发送分析数据:例如,当用户导航到另一个页面时。在这种情况下,浏览器可能即将卸载页面,此时浏览器可能会选择不发送异步 XMLHttpRequest 请求。
过去,网页曾尝试延迟页面卸载足够长的时间来发送数据。为此,它们使用了变通方法,例如:
- 通过阻塞的同步
XMLHttpRequest调用提交数据。 - 创建一个
<img>元素并设置其src。大多数用户代理会延迟卸载以加载图像。 - 创建无操作循环(no-op loop)持续几秒钟。
所有这些方法都会阻塞文档的卸载,这会减慢导航到下一页的速度。下一页无法避免这种情况,因此新页面看起来很慢,尽管这是前一页的过错。
使用 sendBeacon() 方法,数据会在用户代理有机会时异步传输,而不会延迟卸载或下一次导航。这意味着:
- 数据可靠发送
- 异步发送
- 不影响下一页的加载
数据作为 HTTP POST 请求发送。
在会话结束时发送分析数据
网站通常希望在用户完成页面交互后将分析或诊断数据发送到服务器。最可靠的方法是在 visibilitychange 事件上发送数据。
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "hidden") {
navigator.sendBeacon("/log", analyticsData);
}
});
避免 unload 和 beforeunload
过去,许多网站使用 unload 或 beforeunload 事件在会话结束时发送分析数据。然而,这极不可靠。在许多情况下,尤其是在移动设备上,浏览器不会触发 unload、beforeunload 或 pagehide 事件。例如,在以下情况下,这些事件不会触发:
- 用户加载页面并与其交互。
- 完成后,他们切换到另一个应用程序,而不是关闭标签页。
- 稍后,他们使用手机的应用程序管理器关闭了浏览器应用程序。
此外,unload 事件与现代浏览器实现的后退/前进缓存(bfcache)不兼容。一些浏览器(如 Firefox)通过将包含 unload 处理程序的页面排除在 bfcache 之外来处理这种不兼容性,从而损害了性能。其他浏览器(如 Safari 和 Android 上的 Chrome)通过在用户在同一标签页中导航到另一个页面时不触发 unload 事件来处理。
Firefox 也会将包含 beforeunload 处理程序的页面排除在 bfcache 之外。
使用 pagehide 作为回退
为了支持不实现 visibilitychange 的浏览器,请使用 pagehide 事件。与 beforeunload 和 unload 一样,此事件的触发也不太可靠,尤其是在移动设备上。然而,它与 bfcache 兼容。
示例
以下示例为 visibilitychange 事件指定了一个处理程序。该处理程序调用 sendBeacon() 来发送分析数据。
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "hidden") {
navigator.sendBeacon("/log", analyticsData);
}
});
规范
| 规范 |
|---|
| Beacon # sendbeacon-method |
浏览器兼容性
加载中…
另见
visibilitychange事件。- Beacon API 概述页面。
- 不要丢失用户和应用程序状态,请使用页面可见性详细解释了为什么要使用
visibilitychange,而不是beforeunload/unload。 - 页面生命周期 API 提供了关于如何在 Web 应用程序中处理页面生命周期行为的最佳实践指导。
- PageLifecycle.js:一个处理页面生命周期行为中跨浏览器不一致的 JavaScript 库。
- 往返缓存 解释了往返缓存是什么,以及它对各种页面生命周期事件的影响。