今天在 GoogleChrome 的 Samples 仓库中看到了 navigator.sendBeacon
接口案例 demo。javascript
if ('sendBeacon' in navigator) {
window.addEventListener('pagehide', function() {
navigator.sendBeacon(
'https://putsreq.herokuapp.com/4GE2nVUuDoDGsNyKES2G',
'Sent by a beacon!');
}, false);
}
复制代码
打开上面的页面,而后关闭,再点击进入地址 putsreq.herokuapp.com/4GE2nVUuDoD…,就能看见刚才你发送的请求信息。html
在此以前,我已经知道的知识包括:java
navigator.sendBeacon
发送的是 POST 请求第三点,我记不太清了,而后找出了以前翻译的文章确认一下。git
回温到了这块内容:github
Fetch API 支持一个
keepalive
选项,当设置为true
时,保证无论发送请求的页面关闭与否,请求都会持续到结束。chrome
window.addEventListener('unload', {
fetch('/siteAnalytics', {
method: 'POST',
body: getStatistics(),
keepalive: true
});
}
复制代码
Fetch API 语法以下: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 实现方式。app
下面列出是其核心代码:异步
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
事件阶段才启用同步请求,不然都是异步请求。
扩展阅读:
(正文完)
广告时间(长期有效)
我有一位好朋友开了一间猫舍,在此帮她宣传一下。如今猫舍里养的都是布偶猫。若是你也是个爱猫人士而且有须要的话,不妨扫一扫她的【闲鱼】二维码。不买也没关系,看看也行。
(完)