js的sendBeacon方法介绍
Beacon API
是一种轻量级且有效的将网页活动记录到服务器的方法。它是一个 JavaScript API
,可帮助开发人员将少量数据(例如分析或跟踪信息、调试或诊断数据)从浏览器发送到服务器。
在本文中,我们将介绍Beacon API
的相关知识。
什么是sendBeacon
从W3C 的sendBeacon规范来看,Beacon
是:
Web
开发人员可以使用一个接口来安排异步和非阻塞的数据传输,从而最大限度地减少与其他时间关键操作的资源争用,同时确保此类请求仍然得到处理并传输到目的地。
有一些来自浏览器的 HTTP
请求不需要读取甚至等待服务器响应,通常是事件跟踪、状态更新和分析数据。此类请求的特点是:
- 无需访问
HTTP
响应 - 发送后就忘记 - 轻量级 - 不应影响用户体验或占用太多网络带宽
- 发生在后台,无需用户交互
- 关闭页面(又称为页面卸载)时需要可靠发送
Beacon API
的明确目标是为 Web
开发人员提供一个最小的接口来指定数据和端点,然后让浏览器合并请求。
sendBeacon
请求包含了以下几个特点:
- 信标请求不需要响应。这与客户端(浏览器)期望服务器响应的常规
XHR
请求或fetch
请求有很大的不同。 - 即使关闭浏览器,
sendBeacon
请求也保证在页面卸载之前启动。 sendBeacon
请求无需阻塞请求(例如XHR
)即可完成(注意,sendBeacon
请求不是XHR
请求)。- 请求按优先级排列,以避免与时间关键的操作和更高优先级的网络请求竞争。
- 使用
HTTP POST
方法。
sendBeacon的使用
虽然sendBeacon
具有广泛的浏览器支持,但是为了安全起见,我们可以使用下面的代码进行简单的检查简单来测试浏览器支持:
if (navigator.sendBeacon) {navigator.sendBeacon('/log-tracking', data);
} else {// 备选方案
}
sendBeacon
方法采用两个参数:服务器的 URL
和数据。sendBeacon()
方法返回一个布尔值。当请求正确放入队列时它返回true
,否则返回false
。
sendBeacon()
的data
是可选的,并且其类型可以为ArrayBufferView
、Blob
、DOMString
或FormData
。
function sendAnalytics(msg) {if (navigator.sendBeacon) {let data = new FormData();data.append('start', startTime);data.append('end', performance.now());data.append('msg', msg);navigator.sendBeacon('/log-tracking', data);} else {// 备选方案}
}
在上面的示例中,我们发送用户在启动应用程序上花费的时间和时间。我们还发送一个跟踪msg
,捕获用户将执行的活动(例如,单击按钮、滚动到页面部分等)
备选方案
通过使用XMLHttpRequest
或fetch
,我们可以在后台定期发布数据,并且不读取响应也完全可以。
另一种方法是创建一个img元素并利用它向服务器发出 GET
请求的原理实现数据的上传
const img = new Image();
img.src = `http://xxx?${JSON.stringify(data)}`;
问题是当用户关闭页面时,最后一个请求被终止并且无法恢复。换句话说,大量分析数据丢失并导致数据失真。
为了避免关闭页面问题,一个解决方案是在关闭页面(beforeunload
和unload
监听)之前创建一个同步的请求 ,这对用户体验非常不利,因为它会阻止页面卸载(想象一下用户必须等待相当长的时间才能关闭浏览器选项卡)。
注意事项
navigator.sendBeacon()
方法通过HTTP
将少量数据异步发送到 Web
服务器。它旨在与visibilitychange
事件结合使用(但不能与beforeunload
和unload
事件结合使用)。
除了阻止页面卸载之外,浏览器不会像我们期望的那样可靠地触发beforeunload
和unload
这两个事件。
许多开发人员将
unload
事件视为有保证的回调,并将其用作会话结束信号来保存状态并发送分析数据,但这样做非常不可靠,尤其是在移动设备上!在许多典型的卸载情况下,unload
事件不会触发,包括从移动设备上的选项卡切换器关闭选项卡或从应用程序切换器关闭浏览器应用程序。sendBeacon
请求保证在页面卸载之前启动,并且允许运行完成,而无需阻止请求或阻止处理用户交互事件的其他技术。
与其他请求方式不同,sendBeacon
可以由浏览器调度和合并。这就导致 HTTP
请求时间可能会延迟(可以在请求有效负载中包含时间戳数据来解决)。
使用场景
有两个主要场景可以使用Beacon API
:
用户活动跟踪和分析
当我们想要捕获并发送用户活动和行为的分析报告。这些活动可能包括,
- 用户在会话中停留了多长时间?
- 用户使用哪些用户界面控件?
- 要捕获的任何其他类型的信息(比如说
js
的错误)
调试和诊断
我们可能会遇到某个功能可以在本地(开发模式)运行,但在客户环境(生产模式)中无法按预期运行的情况,在这种情况下可以逻辑地发送这些轻量级信标请求来记录有用的跟踪路径信息并根据需要进行调试、排查错误。
sendBeacon 的数据限制
浏览器对sendBeacon
发送的数据大小都是由一定的限制的,以确保请求能够快速、及时地完成。这里没有具体说明限制的数值是因为不同的浏览器供应商的实际实现可以有所不同(不过在w3c的beacon相关的issue中提到了限制大小为64kb
,当然这是非标准的)。