Start · Sprachen · JavaScript · Referenz · BackgroundFetchRecord

BackgroundFetchRecord

Schnittstelle

Steht für ein einzelnes Anfrage-/Antwort-Paar eines Background Fetch und gibt Zugriff auf den <code>Request</code> und die zugehörige <code>Response</code>.

seit JavaScript Experimentell: Chrome/Edge 74+, Opera; nicht in Fi Kategorie: webapi

Signatur

interface BackgroundFetchRecord

Beschreibung

Die Schnittstelle BackgroundFetchRecord gehört zur Background Fetch API. Mit dieser API kann ein Service Worker große Downloads wie Videos, Podcasts oder Spiel-Assets im Hintergrund erledigen, auch wenn der Nutzer die Seite schon geschlossen hat. Ein Background Fetch kann mehrere Anfragen enthalten. Für jede Anfrage gibt es genau einen BackgroundFetchRecord.

Einen Record erzeugt man nicht selbst. Man bekommt ihn über BackgroundFetchRegistration.match() (ein Record) oder BackgroundFetchRegistration.matchAll() (ein Array von Records). Die Schnittstelle hat nur zwei schreibgeschützte Eigenschaften:

  • request: das Request-Objekt der Anfrage, zum Beispiel für den Zugriff auf request.url.
  • responseReady: ein Promise<Response>. Es wird erfüllt, sobald die Antwort vollständig da ist, und abgelehnt, wenn die Anfrage fehlschlägt oder abgebrochen wird.

Am häufigsten nutzt man die Records im Service Worker, und zwar im Handler für backgroundfetchsuccess. Dort liest man die Antworten aus und legt sie zum Beispiel mit der Cache API dauerhaft ab. Im Handler für backgroundfetchfail kann man prüfen, welche Teilanfragen nicht geklappt haben.

Parameter

Name Typ Default Beschreibung
$request Request Eigenschaft (schreibgeschützt): die ursprüngliche Anfrage dieses Records.
$responseReady Promise<Response> Eigenschaft (schreibgeschützt): Promise, das mit der vollständigen Response erfüllt wird. Schlägt die Anfrage fehl oder wird sie abgebrochen, wird es abgelehnt.

Rückgabewert

Typ
BackgroundFetchRecord
Beschreibung
Kommt aus registration.match() (als Promise<BackgroundFetchRecord | undefined>) oder aus registration.matchAll() (als Promise<BackgroundFetchRecord[]>).

Beispiele

Background Fetch starten (Seite)

// Im Seiten-Skript: Download im Hintergrund anstoßen
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: 'Folge 42 wird geladen', downloadTotal: 60 * 1024 * 1024 }
  );
  console.log('Gestartet:', bgFetch.id);
};

startDownload();
Gestartet: podcast-folge-42

Alle Records nach Erfolg im Cache speichern (Service Worker)

// 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);
      console.log('Gespeichert:', record.request.url);
    }));

    await event.updateUI({ title: 'Download abgeschlossen' });
  })());
});
Gespeichert: https://example.com/media/folge-42.mp3 Gespeichert: https://example.com/media/folge-42-cover.jpg

Einzelnen Record per URL abfragen

// sw.js
self.addEventListener('backgroundfetchsuccess', (event) => {
  event.waitUntil((async () => {
    const record = await event.registration.match('/media/folge-42-cover.jpg');
    if (!record) return;
    const response = await record.responseReady;
    console.log(record.request.method, response.status, response.headers.get('content-type'));
  })());
});
GET 200 image/jpeg

Fehlgeschlagene Teilanfragen erkennen

// sw.js
self.addEventListener('backgroundfetchfail', (event) => {
  event.waitUntil((async () => {
    const records = await event.registration.matchAll();
    for (const record of records) {
      try {
        const response = await record.responseReady;
        if (!response.ok) console.warn('HTTP-Fehler', response.status, record.request.url);
      } catch (err) {
        console.warn('Keine Antwort für', record.request.url, err.name);
      }
    }
    console.log('Grund:', event.registration.failureReason);
  })());
});
HTTP-Fehler 404 https://example.com/media/folge-42-cover.jpg Grund: bad-status

// Wichtig · Fallstricke

  • Experimentell und nur in Chromium: Die API gibt es in Chrome, Edge und Opera (ab Version 74). Firefox und Safari unterstützen sie nicht. Prüfe deshalb immer mit 'backgroundFetch' in registration, ob sie verfügbar ist, und sieh einen Fallback vor, etwa ein normales fetch().
  • Die API funktioniert nur in einem sicheren Kontext (HTTPS) und braucht einen aktiven Service Worker.
  • Records sind nur begrenzt verfügbar: match() und matchAll() funktionieren nur, solange registration.recordsAvailable den Wert true hat. Das ist im Wesentlichen innerhalb der Handler für backgroundfetchsuccess und backgroundfetchfail der Fall. Ist der Handler durchgelaufen, werfen beide Methoden einen InvalidStateError. Verpacke die Verarbeitung deshalb in event.waitUntil() und speichere die Antworten dauerhaft, zum Beispiel in der Cache API.
  • Den Body einer Response kann man nur einmal lesen. Wenn du die Antwort cachen und gleichzeitig auswerten willst, arbeite mit response.clone().
  • responseReady wird auch bei HTTP-Fehlern wie 404 erfüllt. Prüfe deshalb zusätzlich response.ok. Abgelehnt wird das Promise nur, wenn gar keine Antwort vorliegt, etwa nach einem Abbruch.
  • Es gibt keinen öffentlichen Konstruktor. Ein Aufruf von new BackgroundFetchRecord() wirft einen TypeError.