Fallback-Antworten verwalten

In bestimmten Situationen kann es sinnvoll sein, eine Fallback-Antwort im Cache zu speichern, falls der Nutzer offline ist. Die Implementierung eines Fallbacks ist eine Alternative zum Caching-Verhalten, das Strategien wie „network-first“ oder „stale- while-revalidation“ bieten.

Ein Fallback ist eine allgemeine Antwort, die für alle Nutzer geeignet ist. Sie ist besser als der Platzhalter, den der Browser standardmäßig bereitstellen würde, wenn eine Anfrage fehlschlägt. Dazu einige Beispiele:

  • Eine Alternative zum „fehlenden Bild“ .
  • Eine HTML-Alternative zur Standardeinstellung "Keine Netzwerkverbindung verfügbar" Seite.

Nur Offlineseite

Wenn Sie lediglich eine benutzerdefinierte Offline-HTML-Seite bereitstellen müssen, finden Sie hier ein Grundschema:

import {offlineFallback} from 'workbox-recipes';
import {setDefaultHandler} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

setDefaultHandler(new NetworkOnly());

offlineFallback();

Der Code oben verwendet setDefaultHandler, um eine reine Netzwerkstrategie als Standard für alle Routen zu verwenden. Anschließend wird das Schema offlineFallback ausgeführt, um das Offline-Fallback bereitzustellen, falls ein Fehler auftritt. Im Schema wird davon ausgegangen, dass Ihre Offline-Fallback-HTML-Datei den Namen offline.html hat und vom Stammverzeichnis Ihres Webservers bereitgestellt wird.

Umfassende Fallbacks

Immer wenn ein Netzwerkfehler oder Cache-Fehler auftritt, werden die von workbox-strategies angebotenen Caching-Strategien konsistent abgelehnt. Dadurch wird das Muster, einen globalen „Catch“, Handler zur Behebung von Fehlern in einer einzelnen Handler-Funktion, sodass Sie verschiedene Fallbacks für verschiedene request.destination-Werte anbieten können.

Im folgenden Beispiel wird das warmStrategyCache-Schema von workbox-recipes verwendet und ein Catch-Handler wird festgelegt, um Elemente bereitzustellen, die im Laufzeitcache vorab im Cache gespeichert werden. Das Pre-Caching von Fallbacks kann jedoch für Ihre Anwendung besser geeignet sein:

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();
  }
});

Im nächsten Schritt werden Fallback-Antworten mithilfe von injectManifest mit den Build-Tools von Workbox vorab im Cache gespeichert und als Fallback dienen, falls bei der Methode matchPrecache ein Fehler auftritt.

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();
  }
});

Ein Beispiel für die zweite Fallback-Einrichtung ist, wenn eine Seite vorzeitig im Cache gespeichert wurde, von der Seite angeforderte Bilder oder andere Assets jedoch nicht. Die Seite kann auch dann aus dem Cache gelesen werden, wenn der Nutzer offline ist, aber bei einem Netzwerkfehler können Fallback-Platzhalter oder alternative Funktionen bereitgestellt werden.

Laufzeitcache erwärmen

Workbox verwaltet separate Caches für Precaching und Laufzeitcaches und es kann Situationen geben, in denen Sie etwas im Voraus speichern möchten, ohne sich auf das Precach zu verlassen, da Sie für Aktualisierungen des Precache-Manifests einen aktualisierten Service Worker bereitstellen müssen.

Wenn Sie den Laufzeitcache vorab mit Assets vorbereiten möchten, können Sie dazu das warmStrategyCache-Schema von workbox-recipes verwenden. Intern wird mit dieser Strategie im install-Ereignis eines Service Workers Cache.addAll aufgerufen.

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});

Fazit

Die Verwaltung von Fallback-Antworten für fehlgeschlagene Anfragen ist mit einem gewissen Aufwand verbunden. Wenn Sie jedoch etwas im Voraus planen, können Sie Ihre Webanwendung so einrichten, dass sie auch offline Inhalte und Funktionen bereitstellt.