Start · Sprachen · JavaScript · Referenz · ServiceWorkerGlobalScope: backgroundfetchsuccess

ServiceWorkerGlobalScope: backgroundfetchsuccess

Ereignis

Wird im Service Worker ausgelöst, wenn ein Background Fetch erfolgreich abgeschlossen wurde, also alle Anfragen erfolgreich beantwortet wurden.

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

Signatur

self.addEventListener("backgroundfetchsuccess", handler)

Beschreibung

Das Ereignis backgroundfetchsuccess wird im ServiceWorkerGlobalScope ausgelöst, sobald eine mit BackgroundFetchManager.fetch() gestartete Background-Fetch-Operation vollständig und erfolgreich abgeschlossen ist. Erfolgreich heißt: Alle Anfragen haben eine Antwort erhalten, und keine davon ist fehlgeschlagen oder wurde abgebrochen. Der Browser führt solche Downloads unabhängig von offenen Tabs aus, zum Beispiel für große Podcast-, Video- oder Offline-Pakete.

Der Handler bekommt ein BackgroundFetchUpdateUIEvent (abgeleitet von BackgroundFetchEvent und ExtendableEvent). Über event.registration erreichen Sie die BackgroundFetchRegistration. Mit registration.matchAll() bzw. match() lesen Sie die heruntergeladenen Antworten aus. Typischerweise legen Sie die Antworten dann über die Cache-API dauerhaft ab und passen die vom Browser angezeigte Fortschrittsanzeige mit event.updateUI() an, etwa mit einem neuen Titel wie „Download abgeschlossen“.

Die Registrierung erfolgt entweder mit self.addEventListener("backgroundfetchsuccess", handler) oder über die Eigenschaft self.onbackgroundfetchsuccess = handler. Asynchrone Arbeit sollten Sie mit event.waitUntil() absichern, damit der Service Worker nicht vorzeitig beendet wird. Schlägt der Fetch fehl, wird stattdessen backgroundfetchfail ausgelöst, bei einem Abbruch backgroundfetchabort.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignistyp, hier "backgroundfetchsuccess".
$handler Pflicht (event: BackgroundFetchUpdateUIEvent) => void Callback-Funktion, die das Ereignisobjekt erhält. Wichtige Mitglieder: event.registration, event.updateUI(options) und event.waitUntil(promise).
$options boolean|AddEventListenerOptions false Optionale Listener-Optionen wie once (bei addEventListener).

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler erhält ein BackgroundFetchUpdateUIEvent.

Beispiele

Heruntergeladene Episoden im Cache speichern (addEventListener)

// sw.js
self.addEventListener('backgroundfetchsuccess', (event) => {
  const bgFetch = event.registration;

  event.waitUntil((async () => {
    const cache = await caches.open('podcasts');
    const records = await bgFetch.matchAll();

    // Jede Anfrage samt Antwort in den Cache übernehmen
    await Promise.all(records.map(async (record) => {
      const response = await record.responseReady;
      await cache.put(record.request, response);
    }));

    // Browser-Fortschrittsanzeige aktualisieren
    await event.updateUI({ title: 'Episode ist offline verfügbar!' });
    console.log(`Background Fetch "${bgFetch.id}" gespeichert (${records.length} Dateien)`);
  })());
});
Background Fetch "episode-42" gespeichert (3 Dateien)

Background Fetch auf der Seite starten

// main.js – im Fenster-Kontext
const startDownload = async () => {
  const reg = await navigator.serviceWorker.ready;
  if (!('backgroundFetch' in reg)) {
    console.log('Background Fetch wird nicht unterstützt');
    return;
  }
  const bgFetch = await reg.backgroundFetch.fetch(
    'episode-42',
    ['/audio/episode-42.mp3', '/img/episode-42.jpg', '/meta/episode-42.json'],
    {
      title: 'Episode 42 wird geladen',
      icons: [{ src: '/icons/download.png', sizes: '192x192', type: 'image/png' }],
      downloadTotal: 60 * 1024 * 1024
    }
  );
  console.log('Gestartet:', bgFetch.id);
};

startDownload();
Gestartet: episode-42

on-Property verwenden und Clients benachrichtigen

// sw.js
self.onbackgroundfetchsuccess = (event) => {
  event.waitUntil((async () => {
    await event.updateUI({ title: 'Fertig!' });
    const clients = await self.clients.matchAll({ includeUncontrolled: true });
    for (const client of clients) {
      client.postMessage({ type: 'bgfetch-done', id: event.registration.id });
    }
  })());
};

// Fehlerfall separat behandeln
self.addEventListener('backgroundfetchfail', (event) => {
  event.waitUntil(event.updateUI({ title: 'Download fehlgeschlagen' }));
});

// Wichtig · Fallstricke

  • Experimentell: Die Background Fetch API gibt es derzeit nur in Chromium-Browsern (Chrome, Edge, Opera). Firefox und Safari unterstützen sie nicht. Prüfen Sie die Unterstützung vorher mit 'backgroundFetch' in registration.
  • Das Ereignis gibt es nur im Service-Worker-Kontext und nur über HTTPS (sicherer Kontext), nicht aber im window-Objekt.
  • event.updateUI() darf pro Ereignis nur einmal aufgerufen werden. Ein zweiter Aufruf löst eine InvalidStateError-Ausnahme aus. Außerdem ist der Aufruf nur während der Ereignisverarbeitung erlaubt.
  • Nach dem Ereignis gibt der Browser die heruntergeladenen Daten wieder frei. Speichern Sie die Antworten also innerhalb von event.waitUntil() im Cache oder in IndexedDB, sonst gehen sie verloren.
  • Ein Background Fetch gilt schon als fehlgeschlagen (Ereignis backgroundfetchfail), wenn eine Antwort einen Nicht-OK-Status wie 404 hat. Behandeln Sie deshalb immer beide Ereignisse.
  • Große Downloads zählen zum Speicherkontingent der Origin. Wird downloadTotal überschritten, bricht der Browser den Fetch ab.