Signatur
Beschreibung
subscribe() ist der zentrale Schritt, um Web-Push-Benachrichtigungen zu aktivieren. Die Methode wird über registration.pushManager eines aktiven Service Workers aufgerufen. Sie fragt – falls noch nicht geschehen – die Benachrichtigungs-Berechtigung beim Nutzer ab, registriert den Browser beim Push-Dienst des Herstellers (z. B. FCM, Mozilla Autopush, Apple Push) und liefert ein PushSubscription-Objekt zurück.
Die Subscription enthält einen Endpoint-URL sowie die öffentlichen Schlüssel p256dh und auth. Diese Daten schickst du an deinen Server. Er nutzt sie später, um über das Web-Push-Protokoll (RFC 8030) verschlüsselte Nachrichten zu senden, die im Service Worker das push-Event auslösen.
In der Praxis sind zwei Optionen Pflicht: userVisibleOnly: true (Chrome und Safari lehnen false ab) und applicationServerKey, also dein öffentlicher VAPID-Schlüssel. Damit weist sich dein Server gegenüber dem Push-Dienst aus. Existiert schon eine Subscription mit demselben Schlüssel, bekommst du diese zurück. Existiert eine mit einem anderen Schlüssel, schlägt der Aufruf fehl.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $options | Object | {} | Konfigurationsobjekt für das Abonnement mit den folgenden Eigenschaften. |
| $options.userVisibleOnly | boolean | false | Sichert zu, dass jede Push-Nachricht eine sichtbare Benachrichtigung auslöst. Chrome und Safari verlangen true, sonst wird das Promise mit NotAllowedError abgelehnt. |
| $options.applicationServerKey | string | ArrayBuffer | TypedArray | DataView | null | null | Öffentlicher VAPID-Schlüssel des Anwendungsservers: ein unkomprimierter P-256-Punkt mit 65 Byte, als Bytes oder als Base64URL-String. Chrome und Safari setzen ihn voraus. |
Rückgabewert
PushSubscription-Objekt, das endpoint, expirationTime, options sowie die Methoden getKey(), toJSON() und unsubscribe() bereitstellt. Mögliche Ablehnungen: NotAllowedError (Berechtigung verweigert oder userVisibleOnly fehlt), InvalidStateError (kein aktiver Service Worker oder anderer Schlüssel bereits abonniert), InvalidAccessError (ungültiger Schlüssel), AbortError (Push-Dienst nicht erreichbar).Beispiele
Grundlegendes Abonnement mit VAPID-Schlüssel
// Base64URL-String in Uint8Array umwandeln
const urlBase64ToUint8Array = (base64String) => {
const padding = '='.repeat((4 - (base64String.length % 4)) % 4);
const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
const raw = atob(base64);
return Uint8Array.from([...raw].map((c) => c.charCodeAt(0)));
};
const VAPID_PUBLIC_KEY = 'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U';
const subscribeUser = async () => {
const registration = await navigator.serviceWorker.register('/sw.js');
await navigator.serviceWorker.ready;
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
});
console.log('Endpoint:', subscription.endpoint);
return subscription;
};
subscribeUser();
Per Button-Klick abonnieren und an den Server senden
const button = document.querySelector('#push-aktivieren');
button.addEventListener('click', async () => {
if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
console.warn('Push wird von diesem Browser nicht unterstützt.');
return;
}
try {
const registration = await navigator.serviceWorker.ready;
// Bestehende Subscription wiederverwenden
let subscription = await registration.pushManager.getSubscription();
if (!subscription) {
subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: 'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U'
});
}
await fetch('/api/push/subscriptions', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(subscription)
});
console.log('Push-Benachrichtigungen aktiviert.');
} catch (err) {
if (err.name === 'NotAllowedError') {
console.warn('Berechtigung verweigert.');
} else {
console.error('Abonnement fehlgeschlagen:', err);
}
}
});
Aufbau der Subscription als JSON
const registration = await navigator.serviceWorker.ready;
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: 'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U'
});
console.log(JSON.stringify(subscription.toJSON(), null, 2));
// Wichtig · Fallstricke
- Sicherer Kontext: Die Methode steht nur unter HTTPS oder auf
localhostzur Verfügung. Außerdem muss ein aktiver Service Worker vorhanden sein. Warte deshalb aufnavigator.serviceWorker.ready. - Nutzeraktion: Firefox und Safari verlangen, dass die Berechtigungsabfrage durch eine Nutzeraktion ausgelöst wird, etwa einen Klick. Ein Aufruf direkt beim Laden der Seite wird abgelehnt oder vom Browser stumm unterdrückt.
- Safari/iOS: Auf iOS und iPadOS funktioniert Web Push erst ab Version 16.4 und nur für Web-Apps, die zum Home-Bildschirm hinzugefügt wurden. Zusätzlich ist ein Web-App-Manifest nötig.
- Schlüsselwechsel: Gibt es bereits eine Subscription mit einem anderen
applicationServerKey, wirft der Aufruf einenInvalidStateError. Rufe vorhersubscription.unsubscribe()auf. - Stumme Pushes verboten: Mit
userVisibleOnly: truemusst du impush-Handler immershowNotification()aufrufen. Sonst zeigen Browser eine Ersatzmeldung an oder entziehen die Berechtigung. - Sicherheit: Endpoint und Schlüssel sind Zugangsdaten. Speichere sie nur serverseitig, übertrage sie über HTTPS und ordne sie einem authentifizierten Nutzer zu. Der private VAPID-Schlüssel darf nie im Client-Code stehen.
- Ablauf: Subscriptions können verfallen. Erhält dein Server vom Push-Dienst den Status
404oder410, lösche die Subscription und abonniere im Client neu.