Javascript專門用於傳送單向請求的幾種可靠方式 - css-tricks

banq發表於2022-03-28

有兩種推薦方式:
  1. 使用 Fetch 的keepalive標誌
  2. Navigator.sendBeacon()函式專門用於傳送單向請求

 

使用 Fetch 的keepalive標誌
如果在使用時將該keepalive標誌設定為,則相應的請求將保持開啟狀態,即使發起該請求的頁面已終止。
案例:

<a href="/some-other-page" id="link">Go to Page</a>

<script>
  document.getElementById('link').addEventListener('click', (e) => {
    fetch("/log", {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      }, 
      body: JSON.stringify({
        some: "data"
      }), 
     [b] keepalive: true[/b]
    });
  });
</script>

 

使用Navigator.sendBeacon()
Navigator.sendBeacon()函式專門用於傳送單向請求(詳細)。
一個基本的實現看起來像這樣,傳送一個POST帶有字串化的 JSON 和一個“text/plain” Content-Type:

navigator.sendBeacon('/log', JSON.stringify({
  some: "data"
}));


但是此 API 不允許您傳送自定義標頭。
因此,為了讓我們以“application/json”的形式傳送資料,我們需要做一些小調整並使用Blob:

<a href="/some-other-page" id="link">Go to Page</a>

<script>
  document.getElementById('link').addEventListener('click', (e) => {
    const blob = new Blob([JSON.stringify({ some: "data" })], { type: 'application/json; charset=UTF-8' });
    navigator.sendBeacon('/log', blob));
  });
</script>


相比fetch():這種方式以低優先順序傳送。
 

Ping屬性
值得一提的是,越來越多的瀏覽器支援該ping屬性。當附加到連結時,它會觸發一個小POST請求:

<a href="http://localhost:3000/other" ping="http://localhost:3000/log">
  Go to Other Page
</a>

這些請求標頭將包含單擊連結的頁面 ( ping-from),以及href該連結的值 ( ping-to):

headers: {
  'ping-from': 'http://localhost:3000/',
  'ping-to': 'http://localhost:3000/other'
  'content-type': 'text/ping'
  // ...other headers
},


它在技術上類似於傳送beacon,但有一些明顯的限制:
  1. 它嚴格限制在連結上的使用,如果您需要跟蹤與其他互動相關的資料,例如按鈕點選或表單提交,這將使其無法啟動。
  2. 瀏覽器支援很好,但不是很好。在撰寫本文時,Firefox 特別沒有預設啟用它。
  3. 您無法隨請求一起傳送任何自定義資料。如前所述,您將獲得的最多的是幾個 ping-*標題,以及其他任何標題。

考慮到所有因素,ping如果您可以傳送簡單的請求並且不想編寫任何自定義 JavaScript,那麼它是一個很好的工具。但是,如果您需要傳送更多實質內容,則可能不是最好的選擇。
 

那麼,我應該接觸哪一個?
使用fetchwithkeepalive或sendBeacon()傳送你的最後一秒請求肯定有權衡。為了幫助辨別哪種方法最適合不同的情況,需要考慮以下幾點:
選擇fetch():_keepalive:

  • 您需要輕鬆地隨請求傳遞自定義標頭。
  • 您想向GET服務發出請求,而不是POST.
  • 您正在支援較舊的瀏覽器(如 IE)並且已經fetch載入了一個 polyfill。

但sendBeacon()在以下情況下可能是更好的選擇:
  • 您正在發出不需要太多自定義的簡單服務請求。
  • 您更喜歡更簡潔、更優雅的 API。
  • 您希望確保您的請求不會與應用程式中傳送的其他高優先順序請求競爭。




 

相關文章