Start · Sprachen · JavaScript · Referenz · BackgroundFetchRegistration

BackgroundFetchRegistration

Schnittstelle

Steht für einen einzelnen Hintergrundabruf der Background Fetch API. Liefert Fortschritt und Status, ermöglicht Abbruch und Zugriff auf die geladenen Antworten.

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

Signatur

interface BackgroundFetchRegistration extends EventTarget

Beschreibung

BackgroundFetchRegistration steht für einen Hintergrundabruf, der mit BackgroundFetchManager.fetch() gestartet wurde. Mit der Background Fetch API lassen sich große Downloads wie Filme, Podcasts oder Offline-Pakete vom Browser erledigen. Der Download läuft auch dann weiter, wenn die Seite oder der Service Worker beendet wurde. Der Browser zeigt dabei eine eigene Fortschrittsanzeige.

Eine Instanz legt man nie selbst an. Man bekommt sie als Rückgabewert von registration.backgroundFetch.fetch() oder registration.backgroundFetch.get(id). Im Service Worker steckt sie außerdem in der Eigenschaft event.registration der Events backgroundfetchsuccess, backgroundfetchfail, backgroundfetchabort und backgroundfetchclick.

Wichtige Eigenschaften (alle nur lesbar):

  • id: die ID, die beim Start vergeben wurde
  • uploadTotal und uploaded: Gesamtgröße und bisher gesendete Bytes der Anfrage-Bodys
  • downloadTotal und downloaded: erwartete Gesamtgröße (0, wenn unbekannt) und bisher geladene Bytes
  • result: "" (läuft noch), "success" oder "failure"
  • failureReason: "", "aborted", "bad-status", "fetch-error", "quota-exceeded" oder "download-total-exceeded"
  • recordsAvailable: true, solange sich die Antworten noch abrufen lassen

Methoden: abort() bricht den Abruf ab und liefert Promise<boolean>. match(request, options) und matchAll(request, options) geben einzelne bzw. alle BackgroundFetchRecord-Objekte zurück. Das Event progress feuert, sobald sich uploaded, downloaded, result oder failureReason ändern. Man abonniert es mit addEventListener("progress", …) oder über die Eigenschaft onprogress.

Parameter

Name Typ Default Beschreibung
$request Request|string Für match() Pflicht, für matchAll() optional: die Anfrage oder URL, deren Datensatz gesucht wird.
$options { ignoreSearch?: boolean, ignoreMethod?: boolean, ignoreVary?: boolean } {} Vergleichsoptionen für match()/matchAll(), genau wie bei Cache.match().

Rückgabewert

Typ
BackgroundFetchRegistration
Beschreibung
Das Objekt, das BackgroundFetchManager.fetch() bzw. get() liefert (bei get() auch undefined, wenn die ID unbekannt ist). match() gibt Promise<BackgroundFetchRecord | undefined> zurück, matchAll() gibt Promise<BackgroundFetchRecord[]> zurück, abort() gibt Promise<boolean> zurück.

Beispiele

Hintergrundabruf starten und Fortschritt anzeigen

// Im Seitenkontext (z. B. main.js)
const startDownload = async () => {
  const swReg = await navigator.serviceWorker.ready;
  if (!('backgroundFetch' in swReg)) {
    console.log('Background Fetch wird nicht unterstützt');
    return;
  }

  const bgFetch = await swReg.backgroundFetch.fetch(
    'podcast-folge-42',
    ['/media/folge-42.mp3', '/media/folge-42-cover.jpg'],
    {
      title: 'Podcast-Folge 42',
      icons: [{ sizes: '192x192', src: '/icons/podcast.png', type: 'image/png' }],
      downloadTotal: 60 * 1024 * 1024 // erwartete Größe: 60 MB
    }
  );

  console.log('Gestartet:', bgFetch.id);

  bgFetch.addEventListener('progress', () => {
    if (!bgFetch.downloadTotal) return;
    const prozent = Math.round((bgFetch.downloaded / bgFetch.downloadTotal) * 100);
    console.log(`Fortschritt: ${prozent} %`);
  });
};

startDownload();
Gestartet: podcast-folge-42 Fortschritt: 12 % Fortschritt: 37 % …

Bestehenden Abruf wiederfinden und abbrechen

const cancelDownload = async (id) => {
  const swReg = await navigator.serviceWorker.ready;
  const bgFetch = await swReg.backgroundFetch.get(id);

  if (!bgFetch) {
    console.log('Kein laufender Abruf mit dieser ID');
    return;
  }

  // Alternativ zu addEventListener: die on-Property
  bgFetch.onprogress = () => console.log('Status:', bgFetch.result || 'läuft', bgFetch.failureReason);

  const abgebrochen = await bgFetch.abort();
  console.log('Abgebrochen:', abgebrochen);
};

cancelDownload('podcast-folge-42');
Status: failure aborted Abgebrochen: true

Ergebnisse im Service Worker in den Cache übernehmen

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

    // Browser-Oberfläche aktualisieren
    await event.updateUI({ title: 'Download abgeschlossen' });
    console.log(`${records.length} Dateien gespeichert (${bgFetch.downloaded} Bytes)`);
  })());
});

self.addEventListener('backgroundfetchfail', (event) => {
  console.log('Fehlgeschlagen:', event.registration.failureReason);
});
2 Dateien gespeichert (62914560 Bytes)

// Wichtig · Fallstricke

  • Kompatibilität: Die API ist experimentell und nur in Chromium-Browsern verfügbar (Chrome, Edge, Opera, Samsung Internet). Firefox und Safari unterstützen sie nicht. Vor der Nutzung sollte man deshalb mit 'backgroundFetch' in registration prüfen, ob sie vorhanden ist, und eine Ausweichlösung mit normalem fetch() vorsehen.
  • Die API gibt es nur in sicheren Kontexten (HTTPS) und nur mit einem aktiven Service Worker.
  • match() und matchAll() funktionieren nur, solange recordsAvailable den Wert true hat. Nach dem Ende der Events backgroundfetchsuccess/backgroundfetchfail verwirft der Browser die Datensätze. Die Antworten müssen deshalb innerhalb von event.waitUntil() in den Cache Storage kopiert werden. Sonst wirft der Aufruf einen InvalidStateError.
  • Stimmt die Angabe downloadTotal nicht, bricht der Abruf mit failureReason === "download-total-exceeded" ab, sobald die angegebene Größe überschritten wird. Ist die Größe unbekannt, lässt man den Wert weg.
  • Jede Antwort mit einem Status außerhalb von 200–299 lässt den ganzen Abruf mit "bad-status" scheitern. Eine teilweise erfolgreiche Registrierung gibt es nicht.
  • Eine ID ist pro Service-Worker-Registrierung eindeutig. Wird fetch() mit einer ID aufgerufen, die gerade aktiv ist, wird das Promise mit einem TypeError abgelehnt.
  • Datenschutz: Der Browser zeigt laufende Abrufe immer sichtbar an, damit Seiten nicht unbemerkt im Hintergrund Daten übertragen.