比如有需求是要讓頁面關閉時, 在數據庫中記錄用戶的一些數據或log日志. 這時就需要在用戶關閉頁面時發起HTTP請求.
做法是對window.onunload設置事件監聽函數, 在函數內發起AJAX請求.
不過有時候頁面已經卸載了, 但請求還沒有發出, 這時就失敗了, 解決這一問題的思路有兩種:
1. 在監聽函數內做一些比較耗時的操作, 保證請求發出;
2. 使用Navigator.sendBeacon().
方法一: 耗時法.
function log() { let xhr = new XMLHttpRequest(); xhr.open('post', '/log', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send('foo=bar'); } window.addEventListener('unload', function(event) { log(); // a time-consuming operation for (let i = 1; i < 10000; i++) { for (let m = 1; m < 10000; m++) { continue; } } });
方法二: Navigator.sendBeacon()
window.addEventListener('unload', logData, false);
function logData() {
navigator.sendBeacon('/log', analyticsData);
}
注意:
1. 增加耗時操作或添加setTimeout都是不合理的, 盡管確實能解決問題.
2. Navigator.sendBeacon()會作為瀏覽器進程任務, 與當前頁面脫鈎, 這是處理這一需求的專用方法.
3. Navigator.sendBeacon()是一個可跨域的POST請求, 且不能回調.
