概念
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() 也可以作为一个传输手段。
参考文章