在某些情況下,您可能需要快取備用回應,以防使用者離線。除了網路優先或過時的重新驗證等策略提供的快取行為外,導入備用機制可替代快取行為。
備用廣告是一種通用的通用回應,是與瀏覽器在要求失敗時預設提供的預留位置。這個預留位置是較合適的預留位置。例如:
- 「缺少圖片」預留位置的替代方案。
- 標準「沒有可用的網路連線」網頁的 HTML 替代網頁。
僅限離線網頁
如果您只需要提供自訂離線 HTML 網頁,但是不必提供其他內容,請參考以下基本方案:
import {offlineFallback} from 'workbox-recipes';
import {setDefaultHandler} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
setDefaultHandler(new NetworkOnly());
offlineFallback();
上述程式碼使用 setDefaultHandler
做為所有路徑的預設策略,使用僅限網路的策略。接著,它會執行 offlineFallback
方案,在發生錯誤時提供離線備用選項。這個做法會假設離線備用 HTML 檔案將命名為 offline.html
,並從網路伺服器的根目錄提供。
完整的備用廣告
每當網路故障或快取失敗,workbox-strategies
提供的快取策略將持續拒絕。如此一來,您就能透過設定全域「catch」處理常式處理單一處理常式函式中任何失敗的模式,以便為不同的 request.destination
值提供不同的備用項。
以下範例使用 workbox-recipes
中的 warmStrategyCache
方案,並設定擷取處理常式,在執行階段快取中提前快取項目。不過,對您的應用程式來說,預先快取備用可能更適合:
import {warmStrategyCache} from 'workbox-recipes';
import {setDefaultHandler, setCatchHandler} from 'workbox-routing';
import {CacheFirst, StaleWhileRevalidate} from 'workbox-strategies';
// Fallback assets to cache
const FALLBACK_HTML_URL = '/offline.html';
const FALLBACK_IMAGE_URL = '/images/image-not-found.jpg';
const FALLBACK_STRATEGY = new CacheFirst();
// Warm the runtime cache with a list of asset URLs
warmStrategyCache({
urls: [FALLBACK_HTML_URL, FALLBACK_IMAGE_URL],
strategy: FALLBACK_STRATEGY,
});
// Use a stale-while-revalidate strategy to handle requests by default.
setDefaultHandler(new StaleWhileRevalidate());
// This "catch" handler is triggered when any of the other routes fail to
// generate a response.
setCatchHandler(async ({request}) => {
// The warmStrategyCache recipe is used to add the fallback assets ahead of
// time to the runtime cache, and are served in the event of an error below.
// Use `event`, `request`, and `url` to figure out how to respond, or
// use request.destination to match requests for specific resource types.
switch (request.destination) {
case 'document':
return FALLBACK_STRATEGY.handle({event, request: FALLBACK_HTML_URL});
case 'image':
return FALLBACK_STRATEGY.handle({event, request: FALLBACK_IMAGE_URL});
default:
// If we don't have a fallback, return an error response.
return Response.error();
}
});
接下來,系統會使用 injectManifest
的 Workbox 建構工具預先快取備用回應,並在使用 matchPrecache
方法發生錯誤時做為備用回應。
import {matchPrecache, precacheAndRoute} from 'workbox-precaching';
import {setDefaultHandler, setCatchHandler} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
// Optional: use the injectManifest mode of one of the Workbox
// build tools to precache a list of URLs, including fallbacks.
precacheAndRoute(self.__WB_MANIFEST);
// Use a stale-while-revalidate strategy to handle requests by default.
setDefaultHandler(new StaleWhileRevalidate());
// This "catch" handler is triggered when any of the other routes fail to
// generate a response.
setCatchHandler(async ({request}) => {
// Fallback assets are precached when the service worker is installed, and are
// served in the event of an error below. Use `event`, `request`, and `url` to
// figure out how to respond, or use request.destination to match requests for
// specific resource types.
switch (request.destination) {
case 'document':
// FALLBACK_HTML_URL must be defined as a precached URL for this to work:
return matchPrecache(FALLBACK_HTML_URL);
case 'image':
// FALLBACK_IMAGE_URL must be defined as a precached URL for this to work:
return matchPrecache(FALLBACK_IMAGE_URL);
default:
// If we don't have a fallback, return an error response.
return Response.error();
}
});
第二種備用設定的應用範例是,如果網頁已事先快取,但網頁要求的圖片 (或其他素材資源) 沒有。使用者離線時,仍可從快取讀取網頁,但如果發生網路錯誤,也可以提供備用預留位置或替代功能。
為執行階段快取暖機
Workbox 會針對預先快取和執行階段快取維護不同的快取,因此您可能會想提前快取內容,而不需要採用預先快取,因為更新預先快取資訊清單時,您必須部署已更新的 Service Worker。
若要提前使用資產加入執行階段快取,您可以使用 workbox-recipes
的 warmStrategyCache
方案。基本上,這項策略會在 Service Worker 的 install
事件中呼叫 Cache.addAll
。
import {warmStrategyCache} from 'workbox-recipes';
import {CacheFirst} from 'workbox-strategies';
// This can be any strategy, CacheFirst used as an example.
const strategy = new CacheFirst();
const urls = [
'/offline.html',
];
warmStrategyCache({urls, strategy});
結語
管理失敗要求的備用回應需要花點工夫,但您可以事先規劃,讓網頁應用程式在使用者離線時,提供一定程度的內容和功能。