Signatur
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 einPromise<BackgroundFetchRegistration>.get(id)liefert die Registrierung mit der angegebenen ID oderundefined.getIds()liefert einPromise<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);
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');
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();
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 normalenfetch()als Ausweichlösung vor. - Die API funktioniert nur in einem sicheren Kontext (HTTPS) und nur mit einem aktiven Service Worker.
- Vergibst du eine
iddoppelt, während der erste Abruf noch läuft, wird das Promise mit einemTypeErrorabgelehnt. Nimm daher eindeutige IDs oder prüfe vorher mitget(). - Ist
downloadTotalzu 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
backgroundfetchsuccessselbst 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.