Start · Sprachen · JavaScript · Referenz · BackgroundFetchManager

BackgroundFetchManager

Schnittstelle

Verwaltet Hintergrundabrufe eines Service Workers: startet neue Downloads mit <code>fetch()</code>, liefert laufende Abrufe per <code>get()</code> und listet ihre IDs mit <code>getIds()</code>.

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

Signatur

interface BackgroundFetchManager

Beschreibung

Die Schnittstelle BackgroundFetchManager gehört zur Background Fetch API. Man kann sie sich wie eine Zuordnung (Map) vorstellen: Jeder Schlüssel ist eine selbst vergebene Abruf-ID, jeder Wert ist ein BackgroundFetchRegistration-Objekt. Eine Instanz erzeugt man nicht selbst. Der Browser stellt sie über ServiceWorkerRegistration.backgroundFetch bereit.

Die API ist für große oder lang laufende Downloads gedacht, etwa Filme, Podcasts, Offline-Pakete oder Spieldaten. Diese Downloads laufen weiter, auch wenn der Nutzer den Tab schließt oder die Seite verlässt. Der Browser zeigt dabei eine eigene Fortschrittsanzeige in seiner Oberfläche. Wenn alles erledigt ist oder etwas schiefgeht, erhält der Service Worker eines der Ereignisse backgroundfetchsuccess, backgroundfetchfail, backgroundfetchabort oder backgroundfetchclick.

Die Schnittstelle bietet drei Methoden:

  • fetch(id, requests, options) startet einen neuen Hintergrundabruf und liefert ein Promise<BackgroundFetchRegistration>.
  • get(id) liefert die Registrierung mit der angegebenen ID oder undefined.
  • getIds() liefert ein Promise<string[]> mit den IDs aller aktiven Abrufe.

Die folgenden Parameter gehören zur zentralen Methode fetch().

Parameter

Name Typ Default Beschreibung
$id Pflicht string Selbst vergebene, eindeutige ID des Abrufs. Ist bereits ein aktiver Abruf mit dieser ID vorhanden, wird das Promise mit einem TypeError abgelehnt.
$requests Pflicht RequestInfo | RequestInfo[] Eine einzelne URL oder ein Request-Objekt oder ein Array davon. Diese Ressourcen werden im Hintergrund geladen.
$options { title?: string, icons?: ImageResource[], downloadTotal?: number } {} title ist der Text der Fortschrittsanzeige. icons ist ein Array aus Objekten mit src, sizes und type. downloadTotal gibt die erwartete Gesamtgröße in Byte an. Wird dieser Wert überschritten, bricht der Abruf ab.

Beispiele

Hintergrund-Download einer Podcast-Folge starten

// Auf der Seite ausführen, der Service Worker ist bereits registriert
const startDownload = async () => {
  if (!('BackgroundFetchManager' in self)) {
    console.log('Background Fetch wird nicht unterstützt');
    return;
  }
  const reg = await navigator.serviceWorker.ready;
  const bgFetch = await reg.backgroundFetch.fetch(
    'podcast-folge-42',
    ['/audio/folge-42.mp3', '/audio/folge-42-cover.jpg'],
    {
      title: 'Folge 42 wird geladen',
      icons: [{ src: '/icons/podcast-192.png', sizes: '192x192', type: 'image/png' }],
      downloadTotal: 60 * 1024 * 1024 // 60 MB
    }
  );
  console.log('Gestartet:', bgFetch.id);
};

startDownload().catch(console.error);
Gestartet: podcast-folge-42

Fortschritt eines laufenden Abrufs abfragen

const zeigeFortschritt = async (id) => {
  const reg = await navigator.serviceWorker.ready;
  const bgFetch = await reg.backgroundFetch.get(id);
  if (!bgFetch) {
    console.log('Kein aktiver Abruf mit dieser ID');
    return;
  }
  bgFetch.addEventListener('progress', () => {
    if (!bgFetch.downloadTotal) return;
    const prozent = Math.round((bgFetch.downloaded / bgFetch.downloadTotal) * 100);
    console.log(`Fortschritt: ${prozent} %`);
  });
};

zeigeFortschritt('podcast-folge-42');
Fortschritt: 37 %

Alle aktiven Abrufe auflisten und abbrechen

const allesAbbrechen = async () => {
  const reg = await navigator.serviceWorker.ready;
  const ids = await reg.backgroundFetch.getIds();
  console.log('Aktive Abrufe:', ids);
  for (const id of ids) {
    const bgFetch = await reg.backgroundFetch.get(id);
    await bgFetch?.abort();
  }
};

allesAbbrechen();
Aktive Abrufe: ['podcast-folge-42']

Ergebnis im Service Worker in den Cache speichern

// sw.js
self.addEventListener('backgroundfetchsuccess', (event) => {
  const bgFetch = event.registration;
  event.waitUntil((async () => {
    const cache = await caches.open('downloads');
    const records = await bgFetch.matchAll();
    await Promise.all(records.map(async (record) => {
      const response = await record.responseReady;
      await cache.put(record.request, response);
    }));
    await event.updateUI({ title: 'Download abgeschlossen' });
  })());
});

// Wichtig · Fallstricke

  • Browserunterstützung: Die API ist experimentell und bisher nur in Chromium-Browsern verfügbar (Chrome, Edge, Opera). Firefox und Safari unterstützen sie nicht. Prüfe deshalb vorher, ob sie vorhanden ist, zum Beispiel mit 'backgroundFetch' in registration, und sieh einen normalen fetch() als Ausweichlösung vor.
  • Die API funktioniert nur in einem sicheren Kontext (HTTPS) und nur mit einem aktiven Service Worker.
  • Vergibst du eine id doppelt, während der erste Abruf noch läuft, wird das Promise mit einem TypeError abgelehnt. Nimm daher eindeutige IDs oder prüfe vorher mit get().
  • Ist downloadTotal zu niedrig angesetzt, bricht der Browser den Abruf ab. Ist der Wert zu hoch, zeigt die Fortschrittsanzeige falsche Werte.
  • Der Browser kann eine Nutzerberechtigung verlangen oder Abrufe ablehnen, wenn der Speicherplatz nicht reicht (QuotaExceededError).
  • Die Ergebnisse speichert der Browser nicht dauerhaft. Sie müssen im Handler von backgroundfetchsuccess selbst abgelegt werden, etwa im Cache Storage.
  • Anfragen mit mode: 'no-cors' werden nicht unterstützt. Für Anfragen an fremde Server muss CORS korrekt konfiguriert sein.