navigator.sendBeacon()方法可用於通過HTTP將少量數據異步傳輸到Web服務器。
使用sendBeacon() 方法會使用戶代理在有機會時異步地向服務器發送數據,同時不會延遲頁面的卸載或影響下一導航的載入性能。這就解決了提交分析數據時的所有的問題:數據可靠,傳輸異步並且不會影響下一頁面的加載。此外,代碼實際上還要比其他技術簡單許多!
const sendBeacon = (url, data = {}) => {
const joinedQueue = navigator.sendBeacon(url, JSON.stringify(data));
console.log('用戶代理把數據加入傳輸隊列' + (joinedQueue ? '成功' : '失敗'));
}
sendBeacon()是以Http POST方法發送請求的。
sendBeacon()第二個參數可接受ArrayBufferView、Blob、FormData、DOMString類型的數據。
sendBeacon()會根據傳入的數據自動設置請求頭,數據類型和對應Content-Type如下:
- Formdata:multipart/form-data
- DOMString:text/plain
如果想傳遞json數據到後端,沒法直接設置請求頭的Content-Type,因此需要明確告訴後端開發人員你傳遞的是json格式的數據。
但是可以通過構建Blob對象間接達到設置Content-Type的效果。
const sendBeacon= (url, data = {}) => {
const blob = new Blob([JSON.stringify(data)], {
type: 'application/json; charset=UTF-8',
});
return navigator.sendBeacon(url, blob);
};
通過Blob也可以發送其他MIME type的數據。
如果瀏覽器不支持sendBeacon()則回退到同步的XMLHttpRequest:
function sendReport(url, data) {
if (navigator.sendBeacon) {
const joinedQueue = sendBeacon(url, data);
if (!joinedQueue) {
syncRequest(url, data);
}
} else {
syncRequest(url, data);
}
}