Signatur
Beschreibung
PushEvent ist das Ereignisobjekt, das ein Service Worker erhält, sobald der Push-Dienst des Browsers (z. B. FCM, Mozilla Autopush oder Apple Push) eine Nachricht an eine bestehende PushSubscription zustellt. Das funktioniert auch dann, wenn keine Seite der Anwendung geöffnet ist. Der Browser startet dafür den Service Worker im Hintergrund.
Das Interface erbt von ExtendableEvent. Deshalb gibt es event.waitUntil(promise). Damit hält man den Service Worker so lange am Leben, bis asynchrone Arbeit abgeschlossen ist, etwa das Anzeigen einer Benachrichtigung mit self.registration.showNotification(). Die wichtigste eigene Eigenschaft ist event.data. Sie enthält ein PushMessageData-Objekt mit den Methoden text(), json(), arrayBuffer() und blob(). Wurde die Nachricht ohne Nutzdaten gesendet, ist der Wert null.
Typische Anwendungsfälle sind Chat- und E-Mail-Benachrichtigungen, Statusmeldungen (Bestellung versandt, Build fehlgeschlagen) und das Anstoßen einer Hintergrund-Synchronisation. Den Konstruktor new PushEvent(type, init) braucht man fast nur für Tests. Im Normalfall erzeugt der Browser das Objekt selbst.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Nur für den Konstruktor: Name des Events, normalerweise "push". |
|
| $eventInitDict | { data?: string | ArrayBuffer | ArrayBufferView } | {} | Nur für den Konstruktor: optionale Nutzdaten, die später als event.data (PushMessageData) bereitstehen. |
Rückgabewert
data (PushMessageData | null, nur lesbar) und der geerbten Methode waitUntil() aus ExtendableEvent.Beispiele
Push-Nachricht im Service Worker als Benachrichtigung anzeigen
// sw.js
self.addEventListener('push', (event) => {
// Nutzdaten lesen – Fallback, falls keine Daten gesendet wurden
const payload = event.data ? event.data.json() : { title: 'Neuigkeit', body: 'Es gibt etwas Neues.' };
event.waitUntil(
self.registration.showNotification(payload.title, {
body: payload.body,
icon: '/icons/icon-192.png',
data: { url: payload.url ?? '/' }
})
);
});
Robustes Parsen: JSON oder Klartext
// sw.js
const parsePush = (data) => {
if (!data) return { title: 'Hinweis', body: '' };
try {
return data.json();
} catch {
// Kein gültiges JSON – als Text behandeln
return { title: 'Hinweis', body: data.text() };
}
};
self.addEventListener('push', (event) => {
const { title, body } = parsePush(event.data);
event.waitUntil(self.registration.showNotification(title, { body }));
});
Asynchrone Arbeit: Daten nachladen, dann benachrichtigen
// sw.js – Push nur als "Klingel", Inhalt wird vom Server geholt
self.addEventListener('push', (event) => {
event.waitUntil((async () => {
const res = await fetch('/api/notifications/latest');
const { count, latest } = await res.json();
// Offene Fenster informieren
const clientsList = await self.clients.matchAll({ type: 'window' });
clientsList.forEach((c) => c.postMessage({ type: 'new-messages', count }));
await self.registration.showNotification(`${count} neue Nachrichten`, {
body: latest.subject,
tag: 'inbox' // ersetzt ältere Benachrichtigung gleichen Tags
});
})());
});
PushEvent im Test selbst erzeugen
// Nur innerhalb eines Service-Worker-Kontexts verfügbar
const testEvent = new PushEvent('push', {
data: JSON.stringify({ title: 'Test', body: 'Hallo Welt' })
});
console.log(testEvent.data.json().title);
// Wichtig · Fallstricke
- Immer eine Benachrichtigung zeigen: Chrome verlangt
userVisibleOnly: truebeim Abonnieren. Zeigt der Service Worker bei einem Push keine Benachrichtigung an, blendet der Browser eine Standardmeldung ein („Diese Website wurde im Hintergrund aktualisiert“). Bei wiederholten Verstößen kann er das Abo auch entziehen. Safari verhält sich ähnlich streng. waitUntil()nicht vergessen: Ohne sie kann der Browser den Service Worker beenden, bevorfetch()odershowNotification()abgeschlossen sind.waitUntil()muss synchron im Handler aufgerufen werden, also nicht erst nach einemawait.event.datakannnullsein. Außerdem wirftdata.json()bei ungültigem JSON einenSyntaxError. Beides sollte man abfangen.- Verfügbarkeit:
PushEventgibt es nur im Service-Worker-Kontext (ServiceWorkerGlobalScope), nicht im Fenster. Eine sichere Verbindung (HTTPS oder localhost) ist Pflicht. Auf iOS/iPadOS funktioniert Push erst ab Version 16.4 und nur für Web-Apps, die zum Home-Bildschirm hinzugefügt wurden. - Sicherheit: Die Nutzdaten sind nach RFC 8291 Ende-zu-Ende-verschlüsselt, und der Server authentifiziert sich per VAPID. Inhalte aus der Nachricht sollte man trotzdem nicht ungeprüft weiterverwenden, zum Beispiel URLs für
clients.openWindow(). Besser ist ein Abgleich mit der eigenen Herkunft (Origin). - Die Größe der Nutzdaten ist begrenzt, je nach Push-Dienst auf etwa 4 KB. Größere Inhalte lädt man besser per
fetch()nach.