工作中的那点事之 JavaScript


工作中的那点事之 JavaScript

sendBeacon利用浏览器的后台任务队列,可以实现在页面关闭后还可以继续发送数据。有数据大小限制(通常为几十KB),所以适用于发送少量数据,尤其是上报埋点信息这种场景。

返回结果为true/falsetrue表示请求排队成功,false表示失败(超过大小限制就会失败,所以可以通过判断返回值为false的时候,改用XHR)。数据传一个超长超长的字符串就可以触发。

特点:

  1. 页面关闭还可以继续发送数据
  2. 有数据大小限制
  3. 支持跨域(异步请求只知道 ajax?sendBeacon 这个新的请求策略也很香!这篇文章有引用 w3c 文档佐证)
  4. 只支持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 编解码

btoaatob

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);

文章作者: 赤蓝紫
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 赤蓝紫 !
评论
  目录