Start · Sprachen · JavaScript · Referenz · ServiceWorkerGlobalScope: backgroundfetchfail

ServiceWorkerGlobalScope: backgroundfetchfail

Ereignis

Wird im Service Worker ausgelöst, wenn ein Hintergrund-Abruf (Background Fetch) fehlgeschlagen ist, also mindestens eine Anfrage nicht erfolgreich abgeschlossen wurde.

seit JavaScript Experimentell: Chromium-Browser (Chrome/Edge 74+), Kategorie: webapi

Signatur

self.addEventListener("backgroundfetchfail", handler)

Beschreibung

Das Ereignis backgroundfetchfail gehört zur Background Fetch API und wird im ServiceWorkerGlobalScope ausgelöst, sobald ein mit BackgroundFetchManager.fetch() gestarteter Hintergrund-Abruf fehlgeschlagen ist. Das passiert, wenn mindestens eine der Netzwerkanfragen im Abruf nicht erfolgreich war, etwa wegen eines Netzwerkfehlers, einer HTTP-Antwort mit Fehlerstatus, einer Überschreitung von downloadTotal oder einem Speicherkontingent, das nicht ausreicht.

Der Handler bekommt ein BackgroundFetchUpdateUIEvent. Über event.registration kommst du an die BackgroundFetchRegistration mit id, failureReason, downloaded und den Methoden match() und matchAll(). Damit kannst du erfolgreich geladene Teile retten, den Fehler protokollieren und mit event.updateUI() die Download-Anzeige des Browsers anpassen, zum Beispiel mit dem Titel „Download fehlgeschlagen“.

Du kannst den Handler mit self.addEventListener("backgroundfetchfail", …) oder über die Eigenschaft self.onbackgroundfetchfail registrieren. Asynchrone Arbeit wie Cache-Zugriffe oder das Senden von Nachrichten an Clients solltest du in event.waitUntil() einschließen, damit der Service Worker nicht vorzeitig beendet wird.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "backgroundfetchfail".
$handler Pflicht (event: BackgroundFetchUpdateUIEvent) => void Callback, der ein BackgroundFetchUpdateUIEvent erhält. Wichtige Mitglieder: event.registration, event.waitUntil(promise) und event.updateUI({ title, icons }).
$options boolean | AddEventListenerOptions false Optionale Listener-Optionen wie once, wie bei addEventListener üblich.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Die Ergebnisse des Abrufs bekommst du über event.registration.

Beispiele

Fehlschlag protokollieren und Anzeige anpassen (addEventListener)

// sw.js
self.addEventListener('backgroundfetchfail', (event) => {
  const reg = event.registration;
  console.log(`Abruf ${reg.id} fehlgeschlagen: ${reg.failureReason}`);

  event.waitUntil(
    event.updateUI({ title: 'Download fehlgeschlagen – bitte erneut versuchen' })
  );
});
Abruf podcast-42 fehlgeschlagen: bad-status

Erfolgreiche Teilantworten in den Cache retten

// sw.js
self.addEventListener('backgroundfetchfail', (event) => {
  event.waitUntil((async () => {
    const reg = event.registration;
    const cache = await caches.open(`partial-${reg.id}`);
    const records = await reg.matchAll();

    let gerettet = 0;
    for (const record of records) {
      const response = await record.responseReady.catch(() => null);
      if (response?.ok) {
        await cache.put(record.request, response);
        gerettet++;
      }
    }
    console.log(`${gerettet} von ${records.length} Dateien gespeichert`);
  })());
});
3 von 5 Dateien gespeichert

Clients benachrichtigen über onbackgroundfetchfail

// sw.js – Alternative über die on-Property
self.onbackgroundfetchfail = (event) => {
  event.waitUntil((async () => {
    const clients = await self.clients.matchAll({ includeUncontrolled: true });
    for (const client of clients) {
      client.postMessage({
        type: 'bgfetch-failed',
        id: event.registration.id,
        reason: event.registration.failureReason
      });
    }
  })());
};

// Seite (main.js): Abruf starten
const startDownload = async () => {
  const swReg = await navigator.serviceWorker.ready;
  if (!('backgroundFetch' in swReg)) return console.warn('Background Fetch nicht unterstützt');
  await swReg.backgroundFetch.fetch('podcast-42', ['/audio/ep42.mp3'], {
    title: 'Episode 42',
    downloadTotal: 60 * 1024 * 1024
  });
};
navigator.serviceWorker.addEventListener('message', (e) => {
  if (e.data.type === 'bgfetch-failed') console.log('Fehler:', e.data.reason);
});
Fehler: fetch-error

// Wichtig · Fallstricke

  • Kompatibilität: Das Ereignis ist experimentell und nur in Chromium-Browsern verfügbar (Chrome, Edge, Opera, Desktop und Android). Firefox und Safari unterstützen es nicht. Prüfe vorher mit 'backgroundFetch' in registration, ob die API da ist, und sieh einen normalen fetch() als Ausweichlösung vor.
  • Das Ereignis wird nur im Service-Worker-Kontext ausgelöst, nicht auf window. Außerdem ist ein sicherer Kontext (HTTPS) nötig.
  • Mögliche Werte von failureReason: "", "aborted", "bad-status", "fetch-error", "quota-exceeded" und "download-total-exceeded". Bricht der Nutzer den Abruf ab, wird stattdessen backgroundfetchabort ausgelöst, nicht backgroundfetchfail.
  • event.updateUI() darf nur einmal aufgerufen werden, und zwar solange das Ereignis aktiv ist. Ein zweiter Aufruf wirft einen InvalidStateError.
  • Rufe matchAll() und match() auf, bevor der Handler endet. Danach ist recordsAvailable false und die Daten werden verworfen.
  • Ohne event.waitUntil() kann der Browser den Service Worker beenden, bevor asynchrone Arbeit fertig ist.