
今天在 GoogleChrome 的 Samples 仓库中看到了 navigator.sendBeacon
接口案例 demo。
if ('sendBeacon' in navigator) {
window.addEventListener('pagehide', function() {
navigator.sendBeacon(
'https://putsreq.herokuapp.com/4GE2nVUuDoDGsNyKES2G',
'Sent by a beacon!');
}, false);
}
打开上面的页面,然后关闭,再点击进入地址 putsreq.herokuapp.com/4GE2nVUuDoD…,就能看见刚才你发送的请求信息。
在此之前,我已经知道的知识包括:
navigator.sendBeacon
发送的是 POST 请求- 传输数据有限制(在 Windows Chorme 浏览器下测试是 65536 个字符(出处))
- 底层是使用 Fetch API 实现的
第三点,我记不太清了,然后找出了之前翻译的文章确认一下。

回温到了这块内容:
Fetch API 支持一个
keepalive
选项,当设置为true
时,保证不管发送请求的页面关闭与否,请求都会持续到结束。
window.addEventListener('unload', {
fetch('/siteAnalytics', {
method: 'POST',
body: getStatistics(),
keepalive: true
});
}
Fetch API 语法如下:
navigator.sendBeacon(url, data);
由此,我想到 navigator.sendBeacon
底层的 Fetch API 实现可能是这样的:
function sendBeacon(url, data) {
try {
fetch(url, {
method: 'POST',
body: data,
keepalive: true
})
} catch {
return false
}
return true
}
我又找了当前 navigator.sendBeacon
的 polyfill 实现方式。
下面列出是其核心代码:
function sendBeacon(url, data) {
var event = this.event && this.event.type;
var sync = event === 'unload' || event === 'beforeunload';
var xhr = 'XMLHttpRequest' in this ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
xhr.open('POST', url, !sync);
xhr.withCredentials = true;
xhr.setRequestHeader('Accept', '*/*');
if (isString(data)) {
xhr.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8');
xhr.responseType = 'text';
} else if (isBlob(data) && data.type) {
xhr.setRequestHeader('Content-Type', data.type);
}
try {
xhr.send(data);
} catch (error) {
return false;
}
return true;
}
底层是借助了 XMLHttpRequest
实例的 open
方法第三个 sync
参数,该参数为 true
时,发送就是同步请求。这里只在页面的 unload
和 beforeunload
事件阶段才启用同步请求,否则都是异步请求。
扩展阅读:
(正文完)
广告时间(长期有效)
我有一位好朋友开了一间猫舍,在此帮她宣传一下。现在猫舍里养的都是布偶猫。如果你也是个爱猫人士并且有需要的话,不妨扫一扫她的【闲鱼】二维码。不买也不要紧,看看也行。

(完)