信标

W3C 候选推荐草案

关于本文件的更多详情
当前版本:
https://www.w3.org/TR/2022/CRD-beacon-20220803/
最新发布版本:
https://www.w3.org/TR/beacon/
最新编辑草案:
https://w3c.github.io/beacon/
历史:
https://www.w3.org/standards/history/beacon
提交历史
测试套件:
https://w3c-test.org/beacon/
实现报告:
https://w3c.github.io/test-results/beacon/
编辑:
(Shopify)
(Compuware公司)
前编辑:
(Google公司) - 至
(微软公司) - 至
反馈:
GitHub w3c/beacon (拉取请求, 新问题, 开放问题)
public-web-perf@w3.org 邮件主题行 [beacon] … 主题 … (存档)
实现情况
Beacon 支持情况?

摘要

本规范定义了一个接口,Web开发者可以使用它来安排异步且非阻塞的数据传递,从而最大程度减少与其他关键操作的资源竞争,同时确保这些请求仍能被处理并送达目标。

本文档状态

本节描述了本文档在发布时的状态。当前 W3C 出版物及该技术报告的最新修订版可在 W3C 技术报告索引 https://www.w3.org/TR/ 查询。

本文档由 Web 性能工作组 作为 推荐轨道下的候选推荐草案发布,详情见 推荐流程

作为候选推荐发布并不代表 W3C 及其会员的认可。候选推荐草案整合了工作组打算在后续候选推荐快照中包含的前一版候选推荐的变更。

本文档为草案,可能随时更新、替换或废止。将本文档作为正在进行的工作之外的内容进行引用是不合适的。

本文档由一个 在 W3C 专利政策 下运作的团体产生。 W3C 维护着 相关专利公开的公开列表 ,该页面还包括专利披露的说明。个人如果确实知晓某项专利且认为其包含 必要声明 ,必须按照 W3C 专利政策第六节 披露相关信息。

本文档受 2021年11月2日 W3C 流程文件 管理。

1. 简介

本节为非规范性内容。

Web 应用通常需要向一个或多个服务器发起请求,用于上报事件、状态更新和分析。这些请求通常不需要客户端处理响应(例如返回 204 或 200 HTTP 响应码且响应体为空),并且不应与其他高优先级操作(如抓取关键资源、响应输入、运行动画等)争夺网络和计算资源。然而,这种单向请求(信标)也负责传递关键的应用和度量数据,导致开发者不得不用高成本的方法来确保其成功送达:

上述送达与处理需求的不匹配,让大多数开发者面临艰难选择,并普遍采用损害用户体验的阻塞技术。本规范定义了一个接口,Web 开发者可以用其安排异步且非阻塞的数据传递,最大限度减少与其他关键操作的资源竞争,同时确保这些请求仍能被处理并送达目标:

以下示例展示了如何使用 sendBeacon() 方法来发送事件、点击和分析数据:

<html>
<script>
  // 发送非阻塞信标以记录客户端事件
  function reportEvent(event) {
    var data = JSON.stringify({
      event: event,
      time: performance.now()
    });
    navigator.sendBeacon('/collector', data);
  }

  // 页面进入后台状态时,发送会话分析信标(Page Visibility API)
  document.addEventListener('visibilitychange', function() {
    if (document.visibilityState === 'hidden') {
      var sessionData = buildSessionReport();
      navigator.sendBeacon('/collector', sessionData);
    }
  });
</script>

<body>
 <a href='http://www.w3.org/' onclick='reportEvent(this)'>
 <button onclick="reportEvent('some event')">点击我</button>
</body>
</html>
注意

上述示例使用了 visibilitychange 事件(定义见 [PAGE-VISIBILITY-2])来触发会话数据的发送。 该事件是页面进入后台状态(如用户切换应用、返回主屏幕等)或页面被卸载时在移动设备上唯一保证触发的事件。 开发者应避免依赖 unload 事件,因为当页面处于后台状态(即 visibilityState 等于 hidden 且进程被移动操作系统终止时, unload 事件不会触发。

通过 sendBeacon() 方法发起的请求不会阻塞或与关键任务竞争,用户代理可优先处理提高网络效率,无需使用阻塞操作确保信标数据送达。

sendBeacon() 不具备且不打算解决的问题:

2. 一致性

除标记为非规范性部分外,本规范中的所有创作指南、图示、示例和注释均为非规范性内容。除此之外,规范中的其它内容均为规范性内容。

本文档中的关键字 MAY(可选)、MUST(必须)、SHOULD(应该)、SHOULD NOT(不应该), 应按照 BCP 14 [RFC2119] [RFC8174] 的说明进行解释,仅当这些词以全部大写形式出现时,如本例所示,才按此解释。

为了便于阅读,本规范中这些关键字未全部使用大写字母。

在算法部分以命令式措辞表达的要求(如“去除所有前导空格字符”或“返回false并中止这些步骤”),应根据引入算法时所用关键字(“must”、“should”、“may”等)来解释其含义。

部分一致性要求以属性、方法或对象为对象提出。此类要求应解释为针对用户代理的要求。

以算法或具体步骤形式表述的一致性要求可以通过任何方式实现,只要最终结果是等价的。(特别地,本规范定义的算法旨在易于理解,并非为了高性能实现。)

3. 信标

3.1 sendBeacon() 方法

WebIDLpartial interface Navigator {
    boolean sendBeacon(USVString url, optional BodyInit? data = null);
};

sendBeacon() 方法会将 data 参数提供的数据发送到 url 参数指定的 URL:

注意
Beacon API 不提供响应回调,建议服务器对这类请求不返回响应体(如返回 204 No Content)。

参数

url

url 参数表示数据要发送到的 URL。

data

data 参数是要发送的 BodyInit 数据。

返回值

sendBeacon() 方法如果用户代理能够成功将数据排队待传输,则返回 true,否则返回 false。

注意

用户代理会限制通过此API发送的数据量:这有助于确保请求能成功送达且对用户和浏览器活动影响最小。如果待排队的 data 超过用户代理限制(详见 HTTP-network-or-cache fetch),则本方法返回 false;返回值为 true 表示浏览器已将数据排队待传输。但由于实际数据传输是异步进行的,该方法不会告知数据传输是否最终成功。

3.2 处理模型

调用 sendBeacon() 方法并传入 url 和可选 data 参数时,需执行以下步骤:

  1. base 设为 this相关设置对象API 基础 URL

  2. origin 设为 this相关设置对象

  3. parsedUrl 设为使用 urlbase 运行 URL 解析器 的结果。如果算法返回错误,或 parsedUrlscheme 不是 "http" 或 "https",则 抛出 "TypeError" 异常并终止这些步骤。

  4. headerList 为一个空列表。
  5. corsMode 为 "no-cors"。
  6. 如果 data 不为 null

    1. transmittedDatacontentType 设为 提取 data 字节流的结果,且 keepalive flag 设为已启用。
    2. 如果 keepalive 启用请求可排队发送的数据量被 transmittedData 的大小超过(见 HTTP-network-or-cache fetch),则返回值设为 false,并终止这些步骤。
      注意

      通过 Beacon API 发起的请求会自动设置 keepalive 标志,开发者也可在使用 Fetch API 时手动设置。所有设置了此标志的请求会共享 Fetch API 内部强制执行的在途配额限制。

    3. 如果 contentType 不为 null:
      • corsMode 设为 "cors"。
      • 如果 contentType 的值是 CORS 安全列表请求头Content-Type 值,则将 corsMode 设为 "no-cors"。
      • headerList 添加一个值为 contentTypeContent-Type 头。
  7. 将返回值设为 true,返回 sendBeacon() 调用,并继续并行执行以下步骤:
    1. req 为新建的 请求,初始化如下:

      方法
      POST
      client
      this相关设置对象
      url
      parsedUrl
      请求头列表
      headerList
      origin
      origin
      keepalive
      true
      请求体
      transmittedData
      mode
      corsMode
      凭据模式
      include
      发起者类型
      "beacon"
    2. 抓取 req

4. 隐私与安全

sendBeacon() 接口提供了异步且非阻塞的数据传递机制。此API可以用于:

传递的数据可能包含敏感信息,例如用户在网页上的活动数据,发送到服务器。虽然这可能带来用户隐私风险,现有方法(如脚本表单提交、图片信标和XHR/fetch请求)也具备类似能力,但存在各种性能折衷:这些请求可能被用户代理中止,除非开发者阻止用户代理处理其他事件(例如发起同步请求或使用空循环等待),且用户代理无法对这些请求进行优先级调度和合并,以优化系统资源使用。

sendBeacon() 发起的请求具有以下属性:

因此,从安全角度看,Beacon API 遵循开发者当前所用方法的安全策略。同样,从隐私角度看,最终请求会在API调用时或页面可见性变化时立即发起,这限制了暴露的信息(如用户IP地址)仅限于开发者可访问的现有生命周期事件。不过,用户代理可能考虑采用其他方法将此类请求展示给用户,以提高透明度。

相比其他方案,sendBeacon() API有两点限制:不提供回调方法,负载大小可由用户代理限制。除此之外,sendBeacon() API不受额外限制。用户代理不应跳过或限制对sendBeacon()的处理,因为它可能包含关键应用状态、事件和分析数据。同样,用户代理在“隐私浏览”或类似模式下也不应禁用sendBeacon(),既可避免破坏应用,又可防止暴露用户处于此模式。

A. 致谢

感谢 Alois Reitbauer、Arvind Jain、Anne van Kesteren、Boris Zbarsky、Chase Douglas、Daniel Austin、Jatinder Mann、James Simonsen、Jason Weber、Jonas Sicking、Nick Doty、Philippe Le Hegaret、Todd Reifsteck、Tony Gentilcore、William Chan 和 Yoav Weiss 对本工作的贡献。

B. 参考文献

B.1 规范性引用

[fetch]
Fetch 标准。Anne van Kesteren。WHATWG。 动态标准。网址:https://fetch.spec.whatwg.org/
[html]
HTML 标准。Anne van Kesteren; Domenic Denicola;Ian Hickson;Philip Jägenstedt;Simon Pieters。WHATWG。动态标准。网址:https://html.spec.whatwg.org/multipage/
[RFC2119]
用于RFC中指示要求级别的关键词。S. Bradner。IETF。1997年3月。最佳当前实践。网址:https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC2119关键词中大写与小写的歧义。B. Leiba。IETF。2017年5月。最佳当前实践。网址:https://www.rfc-editor.org/rfc/rfc8174
[url]
URL 标准。Anne van Kesteren。WHATWG。 动态标准。网址:https://url.spec.whatwg.org/
[webidl]
Web IDL 标准。Edgar Chen;Timothy Gu。 WHATWG。动态标准。网址:https://webidl.spec.whatwg.org/

B.2 参考性引用

[PAGE-VISIBILITY-2]
页面可见性第2级(Page Visibility Level 2)。Ilya Grigorik;Marcos Caceres。W3C。2022年6月23日。W3C候选推荐。网址:https://www.w3.org/TR/page-visibility-2/
[SERVICE-WORKERS]
服务工作线程1(Service Workers 1)。Alex Russell; Jungkee Song;Jake Archibald;Marijn Kruisselbrink。W3C。2019年11月19日。W3C候选推荐。网址:https://www.w3.org/TR/service-workers-1/