頁面關閉,也能將統計資料傳送到Web 伺服器
阿新 • • 發佈:2022-04-06
頁面關閉(前/時/後)將統計資料傳送到 Web 伺服器的方案:
一、XMLHttpRequest
缺點:定時器(setInterval)間隔時間不好把握,Ajax 也會浪費大量的資源。
setInterval(() => { $.ajax({ type: "method", url: "url", data: "data", dataType: "dataType", success: function (response) { } }); }, interval);
二、beforeunload
當瀏覽器視窗關閉或者重新整理時,會觸發 beforeunload 事件。當前頁面不會直接關閉,可以點選確定按鈕關閉或重新整理,也可以取消關閉或重新整理。
window.addEventListener('beforeunload', function (event) {
// Cancel the event as stated by the standard.
event.preventDefault();
// Chrome requires returnValue to be set.
event.returnValue = '';
});
三、unload
當文件或一個子資源正在被解除安裝時, 觸發 unload 事件。
window.addEventListener('unload', function(event) {
console.log('unload');
});
方案二和方案三的缺點:
- 無法獲取使用者取消/確認的回撥
- 無法區分重新整理/關閉
四、websocket
雙方傳送資料很及時。若客戶端離線,伺服器端馬上就知道了。
但若只是個小專案,感覺有點重了。
五、img元素
建立一個 img 元素並設定 src
,但是大部分瀏覽器會延遲解除安裝(unload)文件以載入影象。
六、Beacon【推薦】
特點:
- 通過 HTTP POST 將少量資料(<64 KB)非同步傳輸,可靠性好
- 這個請求不需要響應,保證在頁面的 unload 狀態從發起到完成之前被髮送。
- 不會阻塞頁面解除安裝,也就不會影響下一導航的載入
- 支援跨域
- 不支援自定義請求頭
語法:
navigator.sendBeacon(url);
navigator.sendBeacon(url, data);
示例1:
window.addEventListener('unload', function (event) {
const data = {name: "beacon"};
navigator.sendBeacon('/log', JSON.stringify(data));
});
示例2:
document.addEventListener('visibilitychange', function logData() {
if (document.visibilityState === 'hidden') {
navigator.sendBeacon('/log', analyticsData);
}
});
七、Fetch keep-alive
keepalive
屬性用於頁面解除安裝時,告訴瀏覽器在後臺保持連線,繼續傳送資料。帶有 keepalive
標誌的 Fetch 是 Navigator.sendBeacon() API
的替代品。
同樣典型的場景就是使用者離開網頁時,向伺服器提交一些使用者的行為統計資料。
開啟了 keepalive
屬性後,網頁就算被關閉了,請求被會繼續執行而不會中斷。
示例:
window.onunload = function() {
fetch('/analytics', {
method: 'POST',
body: "statistics",
keepalive: true
});
};
相比 Beacon API
,他有這麼一些好處:能自定義請求頭,不僅僅侷限於 POST 請求…
總之只是在 Fetch 添加了一個 keepalive 屬性,所以就把他當作一個正常的 Fetch 請求使用就行。