Start · Sprachen · JavaScript · Referenz · FetchEvent.respondWith()

FetchEvent.respondWith()

Methode

Unterbindet die Standard-Netzwerkverarbeitung einer abgefangenen Anfrage und liefert stattdessen eine eigene <code>Response</code> oder ein <code>Promise</code> darauf.

seit JavaScript Baseline: alle modernen Browser (Service Worker) Kategorie: webapi

Signatur

FetchEvent.prototype.respondWith(response)

Beschreibung

Die Methode respondWith() wird innerhalb eines fetch-Event-Handlers in einem Service Worker aufgerufen. Sie teilt dem Browser mit, dass der Service Worker die Antwort auf die abgefangene Anfrage selbst bereitstellt. Dadurch können Sie Antworten aus dem Cache liefern, synthetische Antworten erzeugen, Anfragen umleiten oder eine Offline-Seite anzeigen.

Übergeben wird entweder direkt ein Response-Objekt oder ein Promise, das zu einer Response aufgelöst wird. Der Browser wartet, bis das Promise erfüllt ist, und reicht die Antwort dann an die Seite weiter. Wird das Promise abgelehnt oder mit etwas anderem als einer Response erfüllt, erhält die Seite einen Netzwerkfehler (wie bei einem fehlgeschlagenen fetch()).

Wichtig: respondWith() muss synchron während der Event-Verarbeitung aufgerufen werden – also nicht erst nach einem await oder in einem setTimeout. Die asynchrone Arbeit gehört in das übergebene Promise. Ruft man respondWith() gar nicht auf, führt der Browser die Anfrage ganz normal über das Netzwerk aus.

Parameter

Name Typ Default Beschreibung
$response Pflicht Response | Promise<Response> Die Antwort, die der Seite geliefert werden soll, oder ein Promise, das zu einer Response aufgelöst wird.

Rückgabewert

Typ
void
Beschreibung
Gibt undefined zurück.

Beispiele

Cache-first-Strategie mit Netzwerk-Fallback

// sw.js
self.addEventListener('fetch', (event) => {
  if (event.request.method !== 'GET') return; // Standardverhalten

  event.respondWith(
    (async () => {
      const cached = await caches.match(event.request);
      if (cached) return cached;

      const response = await fetch(event.request);
      // Kopie in den Cache legen (Body kann nur einmal gelesen werden)
      const cache = await caches.open('v1');
      event.waitUntil(cache.put(event.request, response.clone()));
      return response;
    })()
  );
});

Offline-Fallback für Navigationen

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open('offline').then((cache) => cache.add('/offline.html'))
  );
});

self.addEventListener('fetch', (event) => {
  if (event.request.mode !== 'navigate') return;

  event.respondWith(
    fetch(event.request).catch(() => caches.match('/offline.html'))
  );
});

Synthetische JSON-Antwort erzeugen

self.addEventListener('fetch', (event) => {
  const url = new URL(event.request.url);

  if (url.pathname === '/api/status') {
    const body = JSON.stringify({ online: true, source: 'service-worker' });
    event.respondWith(
      new Response(body, {
        status: 200,
        headers: { 'Content-Type': 'application/json' }
      })
    );
  }
});

// Auf der Seite:
// const data = await (await fetch('/api/status')).json();
// console.log(data);
{ online: true, source: 'service-worker' }

Falsch vs. richtig: synchroner Aufruf

// FALSCH: respondWith() nach await -> InvalidStateError
self.addEventListener('fetch', async (event) => {
  const cached = await caches.match(event.request);
  // event.respondWith(cached || fetch(event.request)); // zu spät!
});

// RICHTIG: sofort aufrufen, Asynchrones ins Promise verlagern
self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then((c) => c || fetch(event.request))
  );
});

// Wichtig · Fallstricke

  • Nur synchron aufrufbar: Wird respondWith() nach Abschluss der synchronen Event-Verarbeitung (z. B. nach einem await) aufgerufen, wirft der Browser einen InvalidStateError.
  • Nur einmal pro Event: Ein zweiter Aufruf löst ebenfalls einen InvalidStateError aus. Bei mehreren Listenern gewinnt der erste, der respondWith() aufruft.
  • Response-Body nur einmal lesbar: Soll eine Antwort sowohl gecacht als auch zurückgegeben werden, response.clone() verwenden.
  • Netzwerkfehler bei ungültigem Wert: Ein abgelehntes Promise oder ein Nicht-Response-Wert führt auf der Seite zu einem TypeError beim fetch().
  • Sicherheit/CORS: Opake Antworten (type: "opaque") aus no-cors-Anfragen dürfen nur für passende Anfragemodi zurückgegeben werden; für navigate-Anfragen sind Redirect-Antworten mit redirect: "manual" ungültig. Service Worker laufen nur in sicheren Kontexten (HTTPS oder localhost).
  • Nachgelagerte Arbeit: Für Aufgaben nach dem Ausliefern der Antwort (z. B. Cache-Aktualisierung) event.waitUntil() nutzen, damit der Worker nicht vorzeitig beendet wird.
  • Kompatibilität: In allen modernen Browsern verfügbar (Chrome, Edge, Firefox, Safari 11.1+). In privaten Fenstern einiger Browser (z. B. Firefox) sind Service Worker deaktiviert.