Navigator.sendBeacon()
navigator.sendBeacon()
方法可用于通过 HTTP POST 将少量数据 异步 传输到 Web 服务器。
它主要用于将统计数据发送到 Web 服务器,同时避免了用传统技术(如:XMLHttpRequest
)发送分析数据的一些问题。
语法
navigator.sendBeacon(url);
navigator.sendBeacon(url, data);
参数
url
-
url
参数表明data
将要被发送到的网络地址。 data
可选-
data
参数是将要发送的ArrayBuffer
、ArrayBufferView
、Blob
、DOMString
、FormData
或URLSearchParams
类型的数据。
返回值
当用户代理成功把数据加入传输队列时,sendBeacon()
方法将会返回 true
,否则返回 false
。
描述
这个方法主要用于满足统计和诊断代码的需要,这些代码通常尝试在卸载(unload)文档之前向 Web 服务器发送数据。过早的发送数据可能导致错过收集数据的机会。然而,对于开发者来说保证在文档卸载期间发送数据一直是一个困难。因为用户代理通常会忽略在 unload
事件处理器中产生的异步 XMLHttpRequest
。
过去,为了解决这个问题,统计和诊断代码通常要在
- 发起一个同步
XMLHttpRequest
来发送数据。 - 创建一个
<img>
元素并设置src
,大部分用户代理会延迟卸载(unload)文档以加载图像。 - 创建一个几秒的 no-op 循环。
上述的所有方法都会迫使用户代理延迟卸载文档,并使得下一个导航出现的更晚。下一个页面对于这种较差的载入表现无能为力。
这就是 sendBeacon()
方法存在的意义。使用 sendBeacon()
方法会使用户代理在有机会时异步地向服务器发送数据,同时不会延迟页面的卸载或影响下一导航的载入性能,这意味着:
- 数据发送是可靠的。
- 数据异步传输。
- 不影响下一导航的载入。
数据是通过 HTTP POST 请求发送的。
在会话结束时发送统计数据
网站通常希望在用户完成页面浏览后向服务器发送分析或诊断数据,最可靠的方法是在 visibilitychange
事件发生时发送数据:
document.addEventListener("visibilitychange", function logData() {
if (document.visibilityState === "hidden") {
navigator.sendBeacon("/log", analyticsData);
}
});
避免使用 unload 和 beforeunload
过去,许多网站使用 unload
或 beforeunload
事件以在会话结束时发送统计数据。然而这是不可靠的,在许多情况下(尤其是移动设备)浏览器不会产生 unload
、beforeunload
或 pagehide
事件。下面列出了一种不触发上述事件的情况:
- 用户加载了网页并与其交互。
- 完成浏览后,用户切换到了其他应用程序,而不是关闭选项卡。
- 随后,用户通过手机的应用管理器关闭了浏览器应用。
此外,unload
事件与现代浏览器实现的往返缓存(bfcache)不兼容。在部分浏览器(如:Firefox)通过在 bfcache 中排除包含 unload
事件处理器的页面来解决不兼容问题,但这存在性能损失。其他浏览器,例如 Safari 和 Android 上的 Chrome 浏览器则采取用户在同一标签页下导航至其他页面时不触发 unload
事件的方法来解决不兼容问题。
Firefox 也会在 bfcache 中排除包含 beforeunload
事件处理器的页面。
使用 pagehide 作为回退
可使用 pagehide
事件来代替部分浏览器未实现的 visibilitychange
事件。和 beforeunload
与 unload
事件类似,这一事件不会被可靠地触发(特别是在移动设备上),但它与 bfcache 兼容。
示例
示例代码使用 visibilitychange
事件来调用 sendBeacon()
以发送统计数据。
document.addEventListener("visibilitychange", function logData() {
if (document.visibilityState === "hidden") {
navigator.sendBeacon("/log", analyticsData);
}
});
规范
Specification |
---|
Beacon # sendbeacon-method |
浏览器兼容性
BCD tables only load in the browser
参见
visibilitychange
事件。- Beacon API 概述。
- Don't
lose user and app state, use Page Visibility 解释了为什么你应该使用
visibilitychange
而不是beforeunload
/unload
。 - 网页生命周期 API 提供了有关在 Web 应用程序中处理网页生命周期行为的最佳实践。
- PageLifecycle.js:处理跨浏览器网页生命周期行为不一致的 JavaScript 库。
- Back/forward cache 解释了什么是往返缓存,以及它对各种网页生命周期事件的影响。