Beacon API
为了把尽量多的页面信息传到服务器,很多分析工具需要在页面生命周期中尽量晚的时候向服务器
发送遥测或分析数据。因此,理想的情况下是通过浏览器的 unload
事件发送网络请求。这个事件表示
用户要离开当前页面,不会再生成别的有用信息了。
unload
事件触 发时,分析工具要停止收集信息并把收集到的数据发给服务器。这时候有一个问题,
因为 unload
事件对浏览器意味着没有理由再发送任何结果未知的网络请求(因为页面都要被销毁了)。
例如,在 unload
事件处理程序中创建的任何异步请求都会被浏览器取消。为此,异步 XMLHttpRequest
或 fetch()
不适合这个任务。分析工具可以使用同步 XMLHttpRequest 强制发送请求,但这样做会导
致用户体验问题。浏览器会因为要等待 unload
事件处理程序完成而延迟导航到下一个页面。
为解决这个问题,W3C 引入了补充性的 Beacon API。这个 API 给 navigator 对象增加了一个
sendBeacon()
方法。这个简单的方法接收一个 URL 和一个数据有效载荷参数,并会发送一个 POST
请求。可选的数据有效载荷参数有 ArrayBufferView
、Blob
、DOMString
、FormData
实例。如果请
求成功进入了最终要发送的任务队列,则这个方法返回 true,否则返回 false。
// 发送 POST 请求
// URL: 'https://example.com/analytics-reporting-url'
// 请求负载:'{foo: "bar"}'
navigator.sendBeacon(
'https://example.com/analytics-reporting-url',
'{foo: "bar"}',
);
这个方法虽然看起来只不过是 POST 请求的一个语法糖,但它有几个重要的特性。
-
sendBeacon()
并不是只能在页面生命周期末尾使用,而是任何时候都可以使用。 - 调用
sendBeacon()
后,浏览器会把请求添加到一个内部的请求队列。浏览器会主动地发送队列中的请求。 - 浏览器保证在原始页面已经关闭的情况下也会发送请求。
- 状态码、超时和其他网络原因造成的失败完全是不透明的,不能通过编程方式处理。
- 信标(beacon)请求会携带调用
sendBeacon()
时所有相关的 cookie。