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請求來確保瀏覽器不會無視這個請求。code
如今數據確定能發出去了,然而網速無情,一個同步的請求意味着瀏覽器必須等待整個請求發送完成直至收到整條HTTP迴應。這對於頁面切換來講是致命的延遲。orm
說到這你們應該明白了,Beacon API 的做用就是爲了能讓瀏覽器在相似unload這樣的狀況下成功發送請求,同時不影響下一個頁面的載入。如何使用呢,W3C的例子以下:隊列
window.addEventListener('unload', logData, false); function logData() { navigator.sendBeacon("/log", analyticsData); }
好吧,太簡單了,沒啥可說的了。哦不,簡單確實,可是太簡單了,它隱藏了點細節:事件
sendBeacon
只能用POST
請求來發送信息;同步
sendBeacon
的第二個參數是可選的,若是提供的話,參數類型能夠是ArrayBufferView、Blob、DOMString或者FormData;io
sendBeacon
所收到的HTTP迴應會被無視。實際上即便不無視你也不見得能拿到迴應,由於整個請求發送或者收到迴應的時候,頁面可能早就不存在了;function
sendBeacon
是有返回值的,類型爲bool
:true
表示瀏覽器已經將這個請求歸入隊列稍後處理,false
表示瀏覽器沒法完成這個請求,其緣由不詳,不過一般來講就是瀏覽器的HTTP請求隊列已滿;