Navigator.sendBeacon() 解析

950 阅读2分钟

概念

Navigator.sendBeacon() 用于通过 http post 方法将少量数据通过异步传输的方式发送到服务器。该方法有两个参数,第一个必填参数 url,用于指定传送数据的目标地址,第二个可选参数 data,可以传输 ArrayBuffer,ArrayBufferView,FormData,DomString,Blob,URLSearchParams 格式的数据。成功将数据发送到传输队列后就会得到提示,成功返回 true,失败返回 false。该方法用于统计和诊断代码的需要,不会影响页面的正常卸载和下一个导航的加载性能

实例

为了验证 sendBeacon() 的使用方法,可以在 HTML 文件中编写 sendBeacon() 方法的使用代码,使用 express 搭建一个 web 服务器。浏览器执行 HTML 文件的代码就会通过 sendBeacon() 将数据发送到服务器。

// base.html
<script>
  let url = "http://localhost:3000/log";
  let log = function () {
    // 测试是否支持 Beacon
    if (!navigator.sendBeacon) return true;
    const data = {
      start: new Date().getTime(),
      end: performance.now(),
      url: "base.html",
    };
    const res = navigator.sendBeacon(url, JSON.stringify(data));
    console.log("🚀 ~ file: base.html:36 ~ log ~ res:", res);
  };
  window.addEventListener("visibilitychange", log);
</script>

base.html 文件中,给全局增加了 visibilitychange 事件,当前 tab 页面显示或隐藏的时候就会调用 log 函数,该函数会向服务器发送 data 数据,这里的数据使用的 DOMString 格式的文件,其实就是 text/plain 类型的普通字符串。

// index.js
const express = require("express");

const app = express();
app.use(express.text()); // 解析 body 里面的数据

app.post("/log", (req, res) => {
  console.log("🚀 ~ file: index.js:25 ~ app.post ~ req:", req.body); // {"start":1683028892285,"end":3708.100000143051,"url":"base.html"}
});

app.listen(3000, () => {
  console.log("listen 3000");
});

index.js 文件中,使用 express 启动一个服务器,使用 express.text() 去解析 text/plain 类型的数据,构造一个路由为 /log 的 post 路由,启用3000端口。客户端发送数据后,就会将 body 里面的内容打印出来。

小结

Navigator.sendBeacon() 的使用方法并不复杂,它可以很方便的将数据传输到服务器。在数据上报的时候之前常使用 img 的 src 属性,其实 Navigator.sendBeacon() 也可以作为一个传输手段。

参考文章