Skip to content

Instantly share code, notes, and snippets.

@jokemmy
Last active August 28, 2017 01:55
Show Gist options
  • Save jokemmy/b3067019ca57889c27a014750a6bff60 to your computer and use it in GitHub Desktop.
Save jokemmy/b3067019ca57889c27a014750a6bff60 to your computer and use it in GitHub Desktop.
Beacon API

Beacon API是W3C仍在草案阶段的一项新API,这个API主要用于发送不需要服务器回应的HTTP请求或强制浏览器发送一个请求。

这样说可能有点绕,考虑以下情景:

window.addEventListener('unload', logData, false);

function logData() {
    var client = new XMLHttpRequest();
    client you can find out more.open("POST", "/log", true);
    client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
    client.send(analyticsData);
}

这段代码是在做什么呢?如果做过页面统计、埋点,应该能看出来,这段代码实际上是在用户切换页面时试图向服务器发送一些统计数据。

理想情况下没什么问题,然而由于这个请求是在unload事件的handler当中,浏览器可能会忽略这个请求。因此出现了下面这样的代码:

window.addEventListener('unload', logData, false);

function logData() {
    var client = new XMLHttpRequest();
    client.open("POST", "/log", false); // 注意这里
    client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
    client.send(analyticsData);
}

XMLHttpRequest.open的第三个参数表示这个HTTP请求是否异步发送。这段代码将强制浏览器进行一个同步的HTTP请求来确保浏览器不会无视这个请求。

现在数据肯定能发出去了,然而网速无情,一个同步的请求意味着浏览器必须等待整个请求发送完成直至收到整条HTTP回应。这对于页面切换来说是致命的延迟。

Beacon API

说到这大家应该明白了,Beacon API 的作用就是为了能让浏览器在类似unload这样的情况下成功发送请求,同时不影响下一个页面的载入。如何使用呢,W3C的例子如下:

window.addEventListener('unload', logData, false);

function logData() {
    navigator.sendBeacon("/log", analyticsData);
}

好吧,太简单了,没啥可说的了。哦不,简单确实,但是太简单了,它隐藏了点细节:

sendBeacon只能用POST请求来发送信息;

sendBeacon的第二个参数是可选的,如果提供的话,参数类型可以是ArrayBufferView、Blob、DOMString或者FormData;

sendBeacon所收到的HTTP回应会被无视。实际上即使不无视你也不见得能拿到回应,因为整个请求发送或者收到回应的时候,页面可能早就不存在了;

sendBeacon是有返回值的,类型为bool:true表示浏览器已经将这个请求纳入队列稍后处理,false表示浏览器无法完成这个请求,其原因不详,不过通常来说就是浏览器的HTTP请求队列已满;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment