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是有返回值的,类型为booltrue表示浏览器已经将这个请求纳入队列稍后处理,false表示浏览器无法完成这个请求,其原因不详,不过通常来说就是浏览器的HTTP请求队列已满;


sdbxpjzq
150 声望3 粉丝

人生就像写代码,每一次成长就是一次更新,每一次收获就是一个迭代。所以...得写好代码,写好人生(就算现在写不出好的代码,可至少有一颗迭代的心),付出才可能有回报。


引用和评论

0 条评论