處理 Service Worker 中的範圍要求

確認您的服務工作人員知道在要求部分回應時該如何處理。

某些 HTTP 要求包含 Range: 標頭,表示只應傳回完整資源的一部分。常用於串流音訊或影片內容,以便隨選載入較小的媒體區塊,而不必一次要求所有遠端檔案。

「Service Worker」是位於網頁應用程式和網路之間的 JavaScript 程式碼,可能會攔截傳出的網路要求並產生回應。

過去,範圍要求和服務工作人員無法順暢地進行工作。為避免服務工作人員出現不良結果,請務必採取特殊步驟。幸好,這種情況已開始改變。在展現正確行為的瀏覽器中,透過 Service Worker 傳遞範圍要求時,會「只是工作」。

問題說明

假設具有以下 fetch 事件監聽器的 Service Worker,它會接收每個傳入要求,然後傳送至網路:

self.addEventListener('fetch', (event) => {
  // The Range: header will not pass through in
  // browsers that behave incorrectly.
  event.respondWith(fetch(event.request));
});

在行為不正確的瀏覽器中,如果 event.request 包含 Range: 標頭,系統就會在不發出通知的情況下捨棄該標頭。遠端伺服器收到的要求完全不包含 Range:。這不一定是任何「破壞」的情況,因為伺服器技術上可以傳回具備 200 狀態碼的完整回應主體,即使原始要求中有 Range: 標頭也一樣。但這會導致傳輸的資料量,超過瀏覽器的整體需求。

知道此行為的開發人員可以解決問題,方法是明確檢查是否包含 Range: 標頭;如果有,則不呼叫 event.respondWith() (如果有的話)。如此一來,服務工作處理程序就能有效移除回應產生的圖片,而會改用預設瀏覽器網路邏輯 (即知道如何保留範圍要求)。

self.addEventListener('fetch', (event) => {
  // Return without calling event.respondWith()
  // if this is a range request.
  if (event.request.headers.has('range')) {
    return;
  }

  event.respondWith(fetch(event.request));
});

請放心,大多數開發人員都沒有意識到需要執行這項操作。但您不清楚該「為什麼」應該採用這項做法。最後,這個限制的原因是瀏覽器需要反映基礎規格異動,而已新增這項功能。

修正內容

event.request 傳遞至 fetch() 時,正常運作的瀏覽器可以正確保留 Range: 標頭。這表示初始範例中的 Service Worker 程式碼可讓遠端伺服器查看 Range: 標頭 (如果瀏覽器已設定該標頭):

self.addEventListener('fetch', (event) => {
  // The Range: header will pass through in browsers
  // that behave correctly.
  event.respondWith(fetch(event.request));
});

伺服器現在有機會正確處理範圍要求,並傳回包含 206 狀態碼的部分回應。

哪些瀏覽器可以正常運作?

較新版本的 Safari 具有正確功能。從 87 版開始,Chrome 和 Edge 也可以正常運作。

Firefox 尚未修正這項行為,截至 2020 年 10 月為止,因此您在部署服務工作人員的程式碼至實際工作環境時,可能還是需要考量這一點。

只要在網路平台測試資訊主頁的「在網路要求中加入範圍標頭」列,就能確認特定瀏覽器是否已修正這項行為。

系統會如何處理來自快取的放送範圍要求?

服務工作處理程序不僅可將要求傳送到網路,還有許多其他功能。常見的用途是將音訊和影片檔案等資源新增至本機快取。接著,Service Worker 就能完成來自該快取的要求,完全略過網路。

所有瀏覽器 (包括 Firefox) 皆支援在 fetch 處理常式中檢查要求、檢查 Range: 標頭是否存在,然後使用快取提供的 206 回應在本機執行要求。不過,要正確剖析 Range: 標頭,並只傳回完整快取回應的適當部分,Service Worker 程式碼仍是不切實際的。

幸運的是,開發人員如果需要協助,可以改用 Workbox 這個程式庫,可簡化常見的 Service Worker 用途。workbox-range-request module 會實作所有必要邏輯,直接從快取提供部分回應。如需這個使用案例的完整方案,請參閱 Workbox 說明文件

這篇文章的主頁橫幅是由 Natalie Rhea Riggs 在 Unsplash 上提供。