Signatur
Beschreibung
Das Ereignis backgroundfetchfail gehört zur Background Fetch API und wird im ServiceWorkerGlobalScope ausgelöst, sobald ein mit BackgroundFetchManager.fetch() gestarteter Hintergrund-Abruf fehlgeschlagen ist. Das passiert, wenn mindestens eine der Netzwerkanfragen im Abruf nicht erfolgreich war, etwa wegen eines Netzwerkfehlers, einer HTTP-Antwort mit Fehlerstatus, einer Überschreitung von downloadTotal oder einem Speicherkontingent, das nicht ausreicht.
Der Handler bekommt ein BackgroundFetchUpdateUIEvent. Über event.registration kommst du an die BackgroundFetchRegistration mit id, failureReason, downloaded und den Methoden match() und matchAll(). Damit kannst du erfolgreich geladene Teile retten, den Fehler protokollieren und mit event.updateUI() die Download-Anzeige des Browsers anpassen, zum Beispiel mit dem Titel „Download fehlgeschlagen“.
Du kannst den Handler mit self.addEventListener("backgroundfetchfail", …) oder über die Eigenschaft self.onbackgroundfetchfail registrieren. Asynchrone Arbeit wie Cache-Zugriffe oder das Senden von Nachrichten an Clients solltest du in event.waitUntil() einschließen, damit der Service Worker nicht vorzeitig beendet wird.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "backgroundfetchfail". |
|
| $handler Pflicht | (event: BackgroundFetchUpdateUIEvent) => void | Callback, der ein BackgroundFetchUpdateUIEvent erhält. Wichtige Mitglieder: event.registration, event.waitUntil(promise) und event.updateUI({ title, icons }). |
|
| $options | boolean | AddEventListenerOptions | false | Optionale Listener-Optionen wie once, wie bei addEventListener üblich. |
Rückgabewert
addEventListener gibt nichts zurück. Die Ergebnisse des Abrufs bekommst du über event.registration.Beispiele
Fehlschlag protokollieren und Anzeige anpassen (addEventListener)
// sw.js
self.addEventListener('backgroundfetchfail', (event) => {
const reg = event.registration;
console.log(`Abruf ${reg.id} fehlgeschlagen: ${reg.failureReason}`);
event.waitUntil(
event.updateUI({ title: 'Download fehlgeschlagen – bitte erneut versuchen' })
);
});
Erfolgreiche Teilantworten in den Cache retten
// sw.js
self.addEventListener('backgroundfetchfail', (event) => {
event.waitUntil((async () => {
const reg = event.registration;
const cache = await caches.open(`partial-${reg.id}`);
const records = await reg.matchAll();
let gerettet = 0;
for (const record of records) {
const response = await record.responseReady.catch(() => null);
if (response?.ok) {
await cache.put(record.request, response);
gerettet++;
}
}
console.log(`${gerettet} von ${records.length} Dateien gespeichert`);
})());
});
Clients benachrichtigen über onbackgroundfetchfail
// sw.js – Alternative über die on-Property
self.onbackgroundfetchfail = (event) => {
event.waitUntil((async () => {
const clients = await self.clients.matchAll({ includeUncontrolled: true });
for (const client of clients) {
client.postMessage({
type: 'bgfetch-failed',
id: event.registration.id,
reason: event.registration.failureReason
});
}
})());
};
// Seite (main.js): Abruf starten
const startDownload = async () => {
const swReg = await navigator.serviceWorker.ready;
if (!('backgroundFetch' in swReg)) return console.warn('Background Fetch nicht unterstützt');
await swReg.backgroundFetch.fetch('podcast-42', ['/audio/ep42.mp3'], {
title: 'Episode 42',
downloadTotal: 60 * 1024 * 1024
});
};
navigator.serviceWorker.addEventListener('message', (e) => {
if (e.data.type === 'bgfetch-failed') console.log('Fehler:', e.data.reason);
});
// Wichtig · Fallstricke
- Kompatibilität: Das Ereignis ist experimentell und nur in Chromium-Browsern verfügbar (Chrome, Edge, Opera, Desktop und Android). Firefox und Safari unterstützen es nicht. Prüfe vorher mit
'backgroundFetch' in registration, ob die API da ist, und sieh einen normalenfetch()als Ausweichlösung vor. - Das Ereignis wird nur im Service-Worker-Kontext ausgelöst, nicht auf
window. Außerdem ist ein sicherer Kontext (HTTPS) nötig. - Mögliche Werte von
failureReason:"","aborted","bad-status","fetch-error","quota-exceeded"und"download-total-exceeded". Bricht der Nutzer den Abruf ab, wird stattdessenbackgroundfetchabortausgelöst, nichtbackgroundfetchfail. event.updateUI()darf nur einmal aufgerufen werden, und zwar solange das Ereignis aktiv ist. Ein zweiter Aufruf wirft einenInvalidStateError.- Rufe
matchAll()undmatch()auf, bevor der Handler endet. Danach istrecordsAvailablefalseund die Daten werden verworfen. - Ohne
event.waitUntil()kann der Browser den Service Worker beenden, bevor asynchrone Arbeit fertig ist.