向網路伺服器發出要求時,可能會失敗。這可能是因為使用者連線中斷,或遠端伺服器已停止運作。
雖然本說明文件的重點在於處理 Service Worker 中的 GET
要求,但 POST
、PUT
或 DELETE
等其他方法或許就能派上用場。這些方法通常用於與後端 API 通訊,以提供網頁應用程式的資料。如果這些要求在沒有 Service Worker 的情況下失敗,使用者必須在恢復連線時手動重試,而且使用者不一定會記得。
如果這個情況描述您的應用程式,而且同屬一個服務工作處理程序,建議您在使用者恢復連線後,再重試傳送失敗的要求。BackgroundSync API 提供此問題的解決方案。當服務工作處理程序偵測到失敗的網路要求時,可在瀏覽器偵測到連線傳回時註冊以接收 sync
事件。即使使用者離開註冊事件的網頁,系統也可能會傳送 sync
事件,讓回應效率比重試失敗要求的其他方法更有效。
Workbox 利用 workbox-background-sync
模組簡化這個 API,讓 BackgroundSync API 能更容易與其他 Workbox 模組搭配使用。並針對尚未支援 BackgroundSync 的瀏覽器實作備用策略。
基本用法
BackgroundSyncPlugin
會從 workbox-background-sync
模組匯出,可用於將失敗的要求排入佇列,並在日後 sync
事件觸發時重試:
import {BackgroundSyncPlugin} from 'workbox-background-sync';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
const bgSyncPlugin = new BackgroundSyncPlugin('myQueueName', {
maxRetentionTime: 24 * 60 // Retry for max of 24 Hours (specified in minutes)
});
registerRoute(
/\/api\/.*\/*.json/,
new NetworkOnly({
plugins: [bgSyncPlugin]
}),
// An optional third parameter specifies the request method
'POST'
);
此處,BackgroundSyncPlugin
會套用到符合 POST 要求的路徑,到擷取 JSON 資料的 API 路徑。如果使用者處於離線狀態,BackgroundSyncPlugin
會在使用者恢復連線時重試要求,但最多只會顯示一天的時間。
進階用法
workbox-background-sync
也提供 Queue
類別,可讓您例項化並將失敗的要求例項化。和 BackgroundSyncPlugin
的情況一樣,失敗的要求會儲存在「IndexedDB」IndexedDB中,並在瀏覽器認為連線恢復時嘗試嘗試。
建立一個佇列
如要建立佇列,請使用代表佇列名稱的字串將 Queue
物件執行個體化:
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
透過全域 SyncManager
提供的 register()
方法建立,系統會將佇列名稱做為標記名稱的一部分。同時也是索引資料庫提供的 Object Store 名稱。
將要求加入佇列
建立 Queue
執行個體後,您可以使用該執行個體的 pushRequest()
方法,將失敗的要求新增至該執行個體:
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
self.addEventListener('fetch', (event) => {
// Add in your own criteria here to return early if this
// isn't a request that should use background sync.
if (event.request.method !== 'POST') {
return;
}
const bgSyncLogic = async () => {
try {
const response = await fetch(event.request.clone());
return response;
} catch (error) {
await queue.pushRequest({request: event.request});
return error;
}
};
event.respondWith(bgSyncLogic());
});
將要求新增至佇列後,服務工作站收到 sync
事件時,就會自動重試,因為瀏覽器認為網路已可供使用。如果是不支援 BackgroundSync API 的瀏覽器,每次服務工作處理程序啟動時,就會重試要求,較不有效重試失敗的要求,但是採取其他排序方法。
正在測試 workbox-background-sync
測試背景同步處理行為並不容易,但可以透過 Chrome 開發人員工具完成。目前的最佳做法如下:
- 載入註冊 Service Worker 的頁面。
- 關閉電腦的網路連線,或關閉網路伺服器。請勿使用 Chrome 開發人員工具中的離線切換鈕!離線核取方塊只會影響來自網頁的要求,但 Service Worker 要求會繼續執行。
- 使用
workbox-background-sync
發出應排入佇列的網路要求。如要查看已排入佇列的要求,您可以查看Chrome DevTools > Application > IndexedDB > workbox-background-sync > requests
。 - 現在請恢復網路連線或重新開啟網路伺服器。
- 前往
Chrome DevTools > Application > Service Workers
強制執行sync
早期事件。輸入workbox-background-sync:<your queue name>
的標記名稱,其中<your queue name>
是您設定的佇列名稱。 - 按一下「同步」按鈕。
- 現在您應該會看到先前失敗的網路要求重試,並完成處理。因此,由於重新發出要求成功,因此 IndexedDB 儲存庫應是空的。
結論
使用 workbox-background-sync
重試失敗的網路要求,是改善應用程式的使用者體驗和可靠性的好方法,例如讓使用者重新提交失敗的 API 要求,以免遺失要傳送至 API 的資料。也能用來填補自有資料 (例如數據分析) 的資料缺口。事實上,workbox-google-analytics
模組會透過 workbox-background-sync
重新嘗試將失敗的資料傳送至 Google Analytics 的要求。
無論您的用途為何,workbox-background-sync
都能簡化這類工作,提升開發人員體驗,並讓您有更多機會改善網頁應用程式的使用者體驗和功能。