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请求队列已满;
兼容性
Beacon API 的兼容性,从目前(2014-4-16 0:32)来说,还没有任何一个浏览器实现。你大概笑了,那就是说这个API是没用的?
并非如此。Chrome已经着手实现这个API,而Firefox似乎已经实现了;IE比较悲催,尚在考虑当中,但是考虑到W3C这项草案的负责人之一是微软的,我想IE不久也会开始实现的。
参考: