1. 程式人生 > 其它 >頁面關閉,也能將統計資料傳送到Web 伺服器

頁面關閉,也能將統計資料傳送到Web 伺服器

頁面關閉(前/時/後)將統計資料傳送到 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 請求使用就行。

原文:頁面關閉,也能將統計資料傳送到Web 伺服器? (xushanxiang.com)