Signatur
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 wurdeuploadTotalunduploaded: Gesamtgröße und bisher gesendete Bytes der Anfrage-BodysdownloadTotalunddownloaded: erwartete Gesamtgröße (0, wenn unbekannt) und bisher geladene Bytesresult:""(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
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();
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');
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);
});
// 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 registrationprüfen, ob sie vorhanden ist, und eine Ausweichlösung mit normalemfetch()vorsehen. - Die API gibt es nur in sicheren Kontexten (HTTPS) und nur mit einem aktiven Service Worker.
match()undmatchAll()funktionieren nur, solangerecordsAvailableden Werttruehat. Nach dem Ende der Eventsbackgroundfetchsuccess/backgroundfetchfailverwirft der Browser die Datensätze. Die Antworten müssen deshalb innerhalb vonevent.waitUntil()in den Cache Storage kopiert werden. Sonst wirft der Aufruf einenInvalidStateError.- Stimmt die Angabe
downloadTotalnicht, bricht der Abruf mitfailureReason === "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 einemTypeErrorabgelehnt. - Datenschutz: Der Browser zeigt laufende Abrufe immer sichtbar an, damit Seiten nicht unbemerkt im Hintergrund Daten übertragen.