From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- files/zh-cn/web/api/beacon_api/index.html | 54 +++++++++++ .../api/beacon_api/using_the_beacon_api/index.html | 104 +++++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 files/zh-cn/web/api/beacon_api/index.html create mode 100644 files/zh-cn/web/api/beacon_api/using_the_beacon_api/index.html (limited to 'files/zh-cn/web/api/beacon_api') diff --git a/files/zh-cn/web/api/beacon_api/index.html b/files/zh-cn/web/api/beacon_api/index.html new file mode 100644 index 0000000000..257c31f9ed --- /dev/null +++ b/files/zh-cn/web/api/beacon_api/index.html @@ -0,0 +1,54 @@ +--- +title: Beacon API +slug: Web/API/Beacon_API +tags: + - SDK + - user behavior tracker + - user tracker + - 同步请求 + - 埋点 + - 数据分析 + - 规范 +translation_of: Web/API/Beacon_API +--- +

{{DefaultAPISidebar("Beacon")}}{{SeeCompatTable}}

+ +

Beacon 接口用于将异步和非阻塞请求发送到服务器。信标(Beacon )请求使用HTTP协议中的POST方法,请求通常不需要响应。这个请求被保证在,页面的unload状态从发起到完成之前,被发送。而并不需要一个阻塞请求,例如 {{domxref("XMLHttpRequest")}} 。

+ +

Beacon API 的示例用例是记录活动并向服务器发送分析数据。

+ +

本文档中描述的接口的示例代码包含在使用信标API中。

+ +

为什么是信标?

+ +

Beacon 接口满足了分析和诊断代码的需要,这些代码通常会尝试在卸载文档之前将数据发送到 web服务器。发送数据的任何过早时机都可能导致错失收集数据的机会。但是,确保在卸载文档期间发送数据是开发人员难以做到的。

+ +

用户代理通常会忽略卸载文档处理程序中的异步 {{domxref("XMLHttpRequest","XMLHttpRequests")}} 请求。若要解决此问题,为了分析和诊断代码,通常会在 {{event("unload")}} 事件或 {{event("beforeunload")}} 事件中创建同步 {{domxref("XMLHttpRequest")}} 请求以提交数据。同步 {{domxref("XMLHttpRequest")}} 请求强制浏览器延迟卸载文档,并使下一个页面跳转看起来较慢。下一页面没有任何办法来避免这种页面加载性能不佳的感觉。

+ +

其他技术也可以用来确保提交数据。其中一种技术是通过创建 Image 元素并在卸载文档处理程序中设置其 src 属性来延迟卸载以提交数据。由于大多数用户代理会延迟文档卸载,以完成挂起的图片加载,因此可以在卸载过程中提交数据。另一种方法是在卸载处理程序中创建一个无操作循环,花费数秒以延迟卸载并将数据提交到服务器。

+ +

但是上述技术不仅代表了较差的编码模式,其中一些还是不可靠的,会导致下一个导航的页面加载性能较差的感觉。信标 API 提供了解决这些问题的标准方法。

+ +

全局环境

+ +

Beacon API 的 {{domxref("Navigator.sendBeacon()")}} 方法用于在全局浏览上下文中向服务器发送数据信标。该方法有两个参数,URL和要在请求中发送的数据data。data参数是可选的,其类型可以是 {{domxref("ArrayBufferView")}}、{{domxref("Blob")}}{{domxref("DOMString")}} {{domxref("FormData")}}如果浏览器成功的以队列形式排列了用于传递的请求,则该方法返回“true”,否则返回“false”。

+ +

生产环境

+ +

Beacon API的 {{domxref("WorkerNavigator.sendBeacon()")}} 方法用于从 {{domxref("WorkerGlobalScope","worker global scope")}} 向服务器发送数据信标。该方法有两个参数,URL和要在请求中发送的数据data。data参数是可选的,其类型可以是 {{domxref("ArrayBufferView")}}、{{domxref("Blob")}}、{{domxref("DOMString")}} 或 {{domxref("FormData")}}。如果浏览器成功的以队列形式排列了用于传递的请求,则该方法返回“true”,否则返回“false”。

+ +

浏览器兼容性

+ +

{{domxref("Navigator.sendBeacon","Navigator.sendBeacon()","Browser_compatibility")}}表说明了该方法具有相对广泛地实现。但是,{{domxref("WorkerNavigator.sendBeacon","WorkerNavigator.sendBeacon()","Browser_compatibility")}}数据显示该方法没有被实现。

+ +

相关知识

+ + diff --git a/files/zh-cn/web/api/beacon_api/using_the_beacon_api/index.html b/files/zh-cn/web/api/beacon_api/using_the_beacon_api/index.html new file mode 100644 index 0000000000..c65861c7cd --- /dev/null +++ b/files/zh-cn/web/api/beacon_api/using_the_beacon_api/index.html @@ -0,0 +1,104 @@ +--- +title: 使用 Beacon API +slug: Web/API/Beacon_API/Using_the_Beacon_API +tags: + - Web 性能 + - 指南 +translation_of: Web/API/Beacon_API/Using_the_Beacon_API +--- +
{{DefaultAPISidebar("Beacon")}}{{SeeCompatTable}}
+ +

Beacon 接口用来调度向 Web 服务器发送的异步非阻塞请求。

+ + + +

这篇文档包含了 Beacon 接口的一些例子,可以在 {{domxref("Beacon_API","Beacon API")}} 查阅对应的 API。

+ + + +

Beacon API 的 {{domxref("Navigator.sendBeacon()")}} ,会在全局上下文中向服务器发起一个 beacon 请求。这个方法需要两个参数:  URL 以及要发送的数据 data 。其中 data 参数是可选的,它的类型可以为 {{domxref("ArrayBufferView")}}, {{domxref("Blob")}}, {{domxref("DOMString")}}, 或者 {{domxref("FormData")}}.

+ +

如果浏览器成功地将 beacon 请求加入到待发送的队列里,这个方法将会返回 true ,否则将会返回 false 。

+ +

下面的例子注册了 {{event("load")}} 事件和  {{event("beforeunload")}} 事件的回调函数, 并且在回调函数里面调用了 sendBeacon() 方法。

+ +
window.onload = window.onunload = function analytics(event) {
+  if (!navigator.sendBeacon) return;
+
+  var url = "https://example.com/analytics";
+  // 创建待发送数据
+  var data = "state=" + event.type + "&location=" + location.href;
+
+  // 发送beacon请求
+  var status = navigator.sendBeacon(url, data);
+
+  // 打印数据以及结果
+  console.log("sendBeacon: URL = ", url, "; data = ", data, "; status = ", status);
+};
+
+ +

接下来的例子创建了一个 {{event("submit")}} 事件的回调函数,并且当submit事件触发时,调用 sendBeacon()方法。

+ +
window.onsubmit = function send_analytics() {
+  var data = JSON.stringify({
+    location: location.href,
+    time: Date()
+  });
+
+  navigator.sendBeacon('/analytics', data);
+};
+
+ +

WorkerNavigator.sendBeacon()

+ +

Beacon API 的 {{domxref("WorkerNavigator.sendBeacon()")}} 的使用方法,跟平常的使用方法完全相同,区别仅在与这个方法存在 {{domxref("WorkerGlobalScope","worker 全局作用域")}} 

+ +

接下来的例子展示了,使用  {{domxref("Worker")}} 发送了一个 beacon 请求,使用了全局上下文的 URL 和数据。

+ +

这是全局上下文的代码片段:

+ +
function worker_send(url, data) {
+  // 创建 worker 对象
+  var myWorker = new Worker("worker-using.js");
+
+  // 向 worker 发送 URL 以及 data
+  myWorker.postMessage([url, data]);
+
+  // 注册回调函数接收来自 worker 的成功或失败信息
+  myWorker.onmessage = function(event) {
+    var msg = event.data;
+    // 打印 worker 的发送状态
+    console.log("Worker reply: sendBeacon() status = " + msg);
+  };
+}
+
+ +

这是 worker 中的代码片段 (worker-using.js):

+ +
onmessage = function(event) {
+  var msg = event.data;
+  // 从 msg 中分离 URL 和 data
+  var url = msg[0];
+  var data = msg[1];
+
+  // 如果浏览器支持在 worker 里面调用 sendBeacon(), 那就发送beacon请求
+  // 否则返回失败信息给全局上下文
+  if (self.navigator.sendBeacon) {
+    var status = self.navigator.sendBeacon(url, data);
+    postMessage(status ? "success" : "fail");
+  } else {
+    postMessage("Worker: self.navigator.sendBeacon is unsupported");
+  }
+}
+
+ +

查看更多

+ + -- cgit v1.2.3-54-g00ecf