工作中的那点事之 JavaScript
Navigator.sendBeacon(埋点)
sendBeacon
利用浏览器的后台任务队列,可以实现在页面关闭后还可以继续发送数据。有数据大小限制(通常为几十KB
),所以适用于发送少量数据,尤其是上报埋点信息这种场景。
返回结果为true/false
。true
表示请求排队成功,false
表示失败(超过大小限制就会失败,所以可以通过判断返回值为false
的时候,改用XHR
)。数据传一个超长超长的字符串就可以触发。
特点:
- 页面关闭还可以继续发送数据
- 有数据大小限制
- 支持跨域(异步请求只知道 ajax?sendBeacon 这个新的请求策略也很香!这篇文章有引用 w3c 文档佐证)
- 只支持
POST
请求
demo
html
1
| <button id="send-btn">sendBeacon</button> <button id="xhr-btn">xhr get</button>
|
js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| function sendBeacon(url, data) { const result = navigator.sendBeacon( url, `data=${btoa(JSON.stringify(data))}` );
if (result) { console.log("beacon send success!"); } }
function sendXhr(url, data) { const xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { console.log("xhr send success!"); } };
xhr.open("get", `${url}?data=${btoa(JSON.stringify(data))}`); xhr.send(); }
const url = "http://localhost:3000/track/v.png"; const data = { name: "clz", type: "svip", };
document.getElementById("send-btn").addEventListener("click", () => { sendBeacon(url, data); });
document.getElementById("xhr-btn").addEventListener("click", () => { sendXhr(url, data); });
|
服务端 js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const express = require("express");
const app = express();
app.use(express.text());
app.post("/track/v.png", (req, res) => { console.log(req.body); res.sendStatus(200); });
app.get("/track/v.png", (req, res) => { console.log(req.query); res.sendStatus(200); });
app.listen(3000, () => { console.log("Server is running on http://localhost:3000"); });
|

从上图中,可以看到sendBeacon
的支持跨域这个特点
base64 编解码
btoa
、atob
1 2
| let encodedData = window.btoa("Hello, world"); let decodedData = window.atob(encodedData);
|
Buffer
nodejs 环境可以利用Buffer
实现
1 2 3 4 5 6 7 8 9 10 11 12 13
| const person = { name: "赤蓝紫", };
const personString = JSON.stringify(person);
const buffer = Buffer.from(personString, "utf8");
const base64 = buffer.toString("base64"); console.log(base64);
const originalString = Buffer.from(base64, "base64").toString("utf8"); console.log(originalString);
|