移除發生錯誤的服務工作者

有時出錯的 Service Worker 會順利部署完成 但這項功能卻發生問題 舉例來說,系統可在註冊時剖析服務工作處理程序,並成功完成安裝程序。 但 fetch 事件中的錯誤程式碼可能會導致其無法回應要求, 會產生空白網頁另一個可能原因是系統會積極快取網頁標記 而 Service Worker 只會針對後續造訪,傳回來自 Cache 例項的過時標記回應。

Service Worker 有許多方法可以緩解 這就是生產網站會遇到的可怕問題 就算如此,您也不會失去一切。您可以透過幾種方法修正問題,讓進度恢復正常。

部署免人工管理的 Service Worker

處理發生錯誤的 Service Worker 通常只需要部署 no-op Service Worker,可在沒有 fetch 事件處理常式的情況下立即安裝及啟動。

// sw.js

self.addEventListener('install', () => {
  // Skip over the "waiting" lifecycle state, to ensure that our
  // new service worker is activated immediately, even if there's
  // another tab open controlled by our older service worker code.
  self.skipWaiting();
});

self.addEventListener('activate', () => {
  // Optional: Get a list of all the current open windows/tabs under
  // our service worker's control, and force them to reload.
  // This can "unbreak" any open windows/tabs as soon as the new
  // service worker activates, rather than users having to manually reload.
  self.clients.matchAll({
    type: 'window'
  }).then(windowClients => {
    windowClients.forEach((windowClient) => {
      windowClient.navigate(windowClient.url);
    });
  });
});
敬上

這個 Service Worker 將安裝並立即透過呼叫 install 事件中的 self.skipWaiting()。 或者,您也可以在 activate 事件中部署其他程式碼,使用 Service Worker 所控制的 WindowClient 強制重新載入任何其他開啟的分頁。

非操作 Service Worker「必須」不含 fetch 事件處理常式,這一點「非常重要」。 如果 Service Worker 不處理要求, 就像沒有任何 Service Worker 一樣,系統會將這些要求傳送至瀏覽器。 部署免人工管理的服務工作站之後,發生錯誤的 Service Worker 之後就可以修正,並以更新的形式部署。

此方法之所以能奏效,部分原因在於瀏覽器採取嚴密的保護措施,防止服務工作處理程序置入 HTTP 快取,而且會對 Service Worker 的內容執行位元組對位元組的檢查。 這些預設值可讓您部署免人工管理的替代項目,快速修正問題。

其他應採取的措施

部署免人工管理的服務工作人員應足以抵禦容易出現的錯誤 但必要時可採取額外措施

如果您不知道舊 Service Worker 的網址,該怎麼辦?

有時候,先前安裝的 Service Worker 的網址不明。 這可能是因為該檔案版本過舊 (例如檔案名稱中包含雜湊)。 在這種情況下,要部署免人工管理的服務工作處理程序,可能與每個可能已註冊的舊 Service Worker 網址相符。 這違反最佳做法 因為開發人員可能不會記得每個部署的 Service Worker 版本的所有雜湊。

幸好,系統在傳送實用的 HTTP 要求標頭時,會同時傳送對 Service Worker 指令碼的要求: Service-Worker。 在網路伺服器上,檢查是否有這個標頭,然後攔截改為提供免人工管理 Service Worker 的要求。 是否達成上述目標,需視您使用的網路伺服器和後端堆疊而定,因此請參閱相關語言的說明文件,瞭解如何完成這項操作。

為日後的 Service Worker 部署項目,請繼續使用未版本化的資產名稱 (例如 sw.js)。 而這之後會大幅減輕作業上的複雜性。

設定 Clear-Site-Data 標頭

有些瀏覽器會取消註冊一個來源的所有 Service Worker, 已設定 'storage' 值的 Clear-Site-Data 回應標頭。 不過,使用這個方法時,請注意以下幾點:

  • 提醒你,這會清除相關來源的「所有」儲存空間。這包括 localStorage、IndexedDB、sessionStorage 和其他儲存空間 (不含來源的 HTTP 快取)。
  • 並非所有瀏覽器都支援這個標頭

由於各標頭的支援情形並非總計,因此不單只是解決問題。 因此,建議您在部署免人工管理 Service 工作站之外,將 Clear-Site-Data 列為建議採取的措施。

損壞並非永久性

當錯誤的服務工作人員 (尤其是大型和知名網站) 幹擾了使用者體驗時,可能會令人心慌,但這類損害會造成暫時的復原!

如果需要部署免人工管理的服務工作站來修正問題, 才真正瞭解問題所在 日後,請確保 Service Worker 僅處理預期收到的要求。 經常在測試環境中進行測試,並只在有信心的情況下部署更新。