Start · Sprachen · JavaScript · Referenz · ServiceWorkerRegistration.pushManager

ServiceWorkerRegistration.pushManager

Eigenschaft

Schreibgeschützte Eigenschaft, die das <code>PushManager</code>-Objekt einer Service-Worker-Registrierung liefert. Damit abonnieren, lesen und kündigen Sie Push-Nachrichten.

seit JavaScript Baseline 2023: Chrome 42+, Edge 17+, Firefox 44+, Kategorie: webapi

Signatur

ServiceWorkerRegistration.pushManager

Beschreibung

Die schreibgeschützte Eigenschaft pushManager eines ServiceWorkerRegistration-Objekts liefert eine Referenz auf das zugehörige PushManager-Interface. Über dieses Objekt steuern Sie die Push-API: Sie legen neue Push-Abonnements an (subscribe()), lesen ein vorhandenes Abonnement aus (getSubscription()) und fragen den Berechtigungsstatus ab (permissionState()).

Push-Nachrichten gehören immer zu einem Service Worker, denn er muss sie auch empfangen, wenn keine Seite der Anwendung geöffnet ist. Deshalb hängt der PushManager an der Registrierung und nicht an window. Üblicherweise warten Sie mit navigator.serviceWorker.ready auf eine aktive Registrierung und greifen dann auf registration.pushManager zu. Im Service Worker selbst steht dasselbe Objekt als self.registration.pushManager bereit.

Das Abonnement (PushSubscription) enthält einen Endpunkt-URL des Push-Dienstes im Browser sowie öffentliche Schlüssel. Diese Daten schicken Sie an Ihren eigenen Server. Er verschickt dann über das Web-Push-Protokoll (mit VAPID-Schlüsseln) Nachrichten, die im Service Worker das push-Ereignis auslösen.

Rückgabewert

Typ
PushManager
Beschreibung
Das PushManager-Objekt dieser Registrierung. Es bietet die Methoden subscribe(), getSubscription() und permissionState() sowie die statische Eigenschaft PushManager.supportedContentEncodings.

Beispiele

Unterstützung prüfen und vorhandenes Abonnement lesen

const pruefePush = async () => {
  if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
    console.log('Push wird nicht unterstützt');
    return null;
  }
  const registration = await navigator.serviceWorker.ready;
  const subscription = await registration.pushManager.getSubscription();
  console.log(subscription ? 'Bereits abonniert' : 'Kein Abonnement vorhanden');
  return subscription;
};

pruefePush();
Kein Abonnement vorhanden

Push abonnieren (VAPID) und an den Server senden

// Wandelt einen Base64url-String in ein Uint8Array um
const urlBase64ToUint8Array = (base64) => {
  const padding = '='.repeat((4 - (base64.length % 4)) % 4);
  const raw = atob((base64 + padding).replace(/-/g, '+').replace(/_/g, '/'));
  return Uint8Array.from(raw, (c) => c.charCodeAt(0));
};

const VAPID_PUBLIC_KEY = 'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U';

document.querySelector('#push-aktivieren').addEventListener('click', async () => {
  const registration = await navigator.serviceWorker.register('/sw.js');
  await navigator.serviceWorker.ready;

  const permission = await Notification.requestPermission();
  if (permission !== 'granted') return;

  const subscription = await registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
  });

  await fetch('/api/push-abos', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(subscription)
  });
  console.log('Abonniert:', subscription.endpoint);
});
Abonniert: https://fcm.googleapis.com/fcm/send/…

Berechtigungsstatus abfragen und Abonnement kündigen

const pushDeaktivieren = async () => {
  const registration = await navigator.serviceWorker.ready;
  const state = await registration.pushManager.permissionState({ userVisibleOnly: true });
  console.log('Berechtigung:', state);

  const subscription = await registration.pushManager.getSubscription();
  if (subscription) {
    const ok = await subscription.unsubscribe();
    console.log('Abgemeldet:', ok);
  }
};

pushDeaktivieren();
Berechtigung: granted Abgemeldet: true

Abonnement im Service Worker erneuern

// sw.js
self.addEventListener('pushsubscriptionchange', (event) => {
  event.waitUntil((async () => {
    const neu = await self.registration.pushManager.subscribe(
      event.oldSubscription?.options ?? { userVisibleOnly: true }
    );
    await fetch('/api/push-abos', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(neu)
    });
  })());
});

// Wichtig · Fallstricke

  • Nur in sicherem Kontext: Die Push-API funktioniert ausschließlich über HTTPS (Ausnahme: localhost). In privaten Fenstern ist pushManager teilweise vorhanden, subscribe() scheitert dort aber.
  • Nutzergeste nötig: Rufen Sie Notification.requestPermission() und subscribe() nur als Reaktion auf eine Nutzeraktion auf, etwa einen Klick. Safari und Firefox blockieren Anfragen ohne Geste, und Chrome drosselt aufdringliche Berechtigungsdialoge.
  • userVisibleOnly: true ist in Chrome und Safari Pflicht. Jede Push-Nachricht muss dann mit showNotification() eine sichtbare Benachrichtigung anzeigen, sonst zeigt der Browser eine allgemeine Meldung oder entzieht die Berechtigung.
  • iOS/iPadOS: Web-Push gibt es erst ab 16.4, und zwar nur für Web-Apps, die zum Home-Bildschirm hinzugefügt wurden. Im normalen Safari-Tab gibt es kein PushManager.
  • Feature-Erkennung: Prüfen Sie 'PushManager' in window oder 'pushManager' in registration, bevor Sie darauf zugreifen.
  • Sicherheit/Datenschutz: Der Endpunkt-URL und die Schlüssel eines Abonnements sind vertraulich. Wer sie kennt, kann (mit Ihrem privaten VAPID-Schlüssel) Nachrichten senden. Übertragen Sie sie nur verschlüsselt, legen Sie sie sicher auf dem Server ab und veröffentlichen Sie niemals den privaten VAPID-Schlüssel.
  • Abonnements können ablaufen oder vom Push-Dienst ungültig gemacht werden. Antwortet der Server mit HTTP 404 oder 410, löschen Sie das Abonnement. Auf pushsubscriptionchange reagieren nicht alle Browser gleich zuverlässig.