Start · Sprachen · JavaScript · Referenz · PushSubscription.toJSON()

PushSubscription.toJSON()

Methode

Gibt ein einfaches Objekt mit <code>endpoint</code>, <code>expirationTime</code> und den Base64url-codierten Schlüsseln <code>p256dh</code> und <code>auth</code> des Push-Abonnements zurück.

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

Signatur

PushSubscription.prototype.toJSON()

Beschreibung

toJSON() ist der Standard-Serialisierer von PushSubscription. Die Methode liefert ein einfaches, JSON-fähiges Objekt mit allen Angaben, die ein Anwendungsserver zum Versand von Web-Push-Nachrichten braucht: die endpoint-URL des Push-Dienstes, die optionale expirationTime und das Objekt keys mit dem öffentlichen ECDH-Schlüssel p256dh und dem Authentifizierungsgeheimnis auth.

Der größte Vorteil: Die Schlüssel liegen bereits als Base64url-codierte Zeichenketten vor. Ohne toJSON() müsste man subscription.getKey('p256dh') und getKey('auth') aufrufen und die zurückgegebenen ArrayBuffer selbst codieren.

Da JSON.stringify() toJSON() automatisch aufruft, reicht in der Praxis oft JSON.stringify(subscription), zum Beispiel direkt im body eines fetch()-Aufrufs. Der direkte Aufruf lohnt sich, wenn man mit einzelnen Feldern arbeiten will, etwa um nur keys.auth zu speichern oder das Objekt vor dem Versand um eigene Daten zu erweitern.

Rückgabewert

Typ
PushSubscriptionJSON (Object)
Beschreibung

Ein einfaches Objekt der Form { endpoint: string, expirationTime: number | null, keys: { p256dh: string, auth: string } }. Die Schlüssel sind Base64url-codiert, ohne Auffüllzeichen (=).

Beispiele

Abonnement abschließen und an den Server senden

// VAPID-Schlüssel (Base64url) in Uint8Array umwandeln
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 subscribeUser = async (vapidPublicKey) => {
  const registration = await navigator.serviceWorker.ready;
  const subscription = await registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: urlBase64ToUint8Array(vapidPublicKey)
  });

  const data = subscription.toJSON();
  console.log(data.endpoint);

  await fetch('/api/push/subscribe', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data)
  });
};
https://fcm.googleapis.com/fcm/send/dXk3…

Einzelne Felder auslesen und erweitern

const registration = await navigator.serviceWorker.ready;
const subscription = await registration.pushManager.getSubscription();

if (subscription) {
  const { endpoint, expirationTime, keys } = subscription.toJSON();
  console.log('Läuft ab:', expirationTime ?? 'nie');
  console.log('auth-Länge:', keys.auth.length);

  // Eigene Metadaten ergänzen
  const payload = { endpoint, keys, userId: 42, locale: navigator.language };
  console.log(JSON.stringify(payload, null, 2));
}
Läuft ab: nie auth-Länge: 22 { "endpoint": "https://…", "keys": { "p256dh": "BNcR…", "auth": "tBHI…" }, "userId": 42, "locale": "de-DE" }

Implizit über JSON.stringify()

const registration = await navigator.serviceWorker.ready;
const subscription = await registration.pushManager.getSubscription();

// JSON.stringify ruft toJSON() automatisch auf
const a = JSON.stringify(subscription);
const b = JSON.stringify(subscription.toJSON());
console.log(a === b);
true

// Wichtig · Fallstricke

  • Nicht mit dem Original verwechseln: Das Ergebnis ist ein totes Datenobjekt. Methoden wie unsubscribe() oder getKey() gibt es darauf nicht. Verwende dafür weiterhin die PushSubscription-Instanz.
  • Kodierung: p256dh und auth sind Base64url-codiert (- und _, ohne =). Serverbibliotheken wie web-push für Node.js erwarten genau dieses Format. atob() kann sie ohne vorherige Umwandlung nicht decodieren.
  • Sicherheit: endpoint und auth gelten als Geheimnisse. Wer sie kennt, kann in Verbindung mit dem VAPID-Schlüssel Nachrichten an den Nutzer senden. Übertrage sie nur über HTTPS, speichere sie serverseitig geschützt und gib sie nicht in Protokollen aus.
  • expirationTime ist in den meisten Browsern null. Verlass dich nicht darauf. Reagiere stattdessen im Service Worker auf das Ereignis pushsubscriptionchange und behandle die Serverantworten 404/410 beim Versand.
  • Kompatibilität: Die Push-API gibt es nur in sicheren Kontexten (HTTPS) und nur mit einem registrierten Service Worker. Auf iOS/iPadOS funktioniert sie erst ab 16.4 und nur für Web-Apps, die zum Home-Bildschirm hinzugefügt wurden.