Navigator.sendBeacon() 關閉網頁時異步發送數據


用戶卸載網頁的時候,有時需要向服務器發一些數據。很自然的做法是在unload事件或beforeunload事件的監聽函數里面,使用XMLHttpRequest對象發送數據。但是,這樣做不是很可靠,因為XMLHttpRequest對象是異步發送,很可能在它即將發送的時候,頁面已經卸載了,從而導致發送取消或者發送失敗。

解決方法就是 AJAX 通信改成同步發送,即只有發送完成,頁面才能卸載。但是,很多瀏覽器已經不支持同步的 XMLHttpRequest 對象了(即open()方法的第三個參數為false)。

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同步發送,很多瀏覽器都已經不支持這種寫法。

同步通信有幾種變通的方法。一種做法是新建一個<img>元素,數據放在src屬性,作為 URL 的查詢字符串,這時瀏覽器會等待圖片加載完成(服務器回應),再進行卸載。另一種做法是創建一個循環,規定執行時間為幾秒鍾,在這幾秒鍾內把數據發出去,然后再卸載頁面。

這些做法的共同問題是,卸載的時間被硬生生拖長了,后面頁面的加載被推遲了,用戶體驗不好。

為了解決這個問題,瀏覽器引入了Navigator.sendBeacon()方法。這個方法還是異步發出請求,但是請求與當前頁面脫鈎,作為瀏覽器的任務,因此可以保證會把數據發出去,不拖延卸載流程。

window.addEventListener('unload', logData, false);

function logData() {
    navigator.sendBeacon('/log', analyticsData);
}

 

Navigator.sendBeacon方法接受兩個參數,第一個參數是目標服務器的 URL,第二個參數是所要發送的數據(可選),可以是任意類型(字符串、表單對象、二進制對象等等)。

navigator.sendBeacon(url, data)


這個方法的返回值是一個布爾值,成功發送數據為true,否則為false。

該方法發送數據的 HTTP 方法是 POST,可以跨域,類似於表單提交數據。它不能指定回調函數。

下面是一個例子。

// HTML 代碼如下
// <body "analytics('start')" οnunlοad="analytics('end')">

function analytics(state) {
    if (!navigator.sendBeacon) return;

    var URL = 'http://example.com/analytics';
    var data = 'state=' + state + '&location=' + window.location;
    navigator.sendBeacon(URL, data);
}

 

————————————————
版權聲明:本文為CSDN博主「霧里看花嘆朦朧」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/hsl0530hsl/article/details/88579958


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM