Signatur
Beschreibung
Die schreibgeschützte Eigenschaft options einer PushSubscription liefert ein Objekt mit den Optionen, die beim Aufruf von PushManager.subscribe() übergeben wurden. Es enthält die Felder userVisibleOnly (boolean) und applicationServerKey (ArrayBuffer oder null).
Wichtig ist das vor allem bei der Rotation des VAPID-Schlüssels: Wenn der Server einen neuen öffentlichen Schlüssel verwendet, kann die Anwendung über subscription.options.applicationServerKey prüfen, ob ein bestehendes Abonnement noch mit dem aktuellen Schlüssel erstellt wurde. Falls nicht, wird es gekündigt und neu angelegt.
Der applicationServerKey wird immer als ArrayBuffer zurückgegeben, auch wenn beim Abonnieren ein Base64url-String oder ein Uint8Array übergeben wurde. Für einen Vergleich muss man beide Seiten also in dieselbe Darstellung umwandeln.
Rückgabewert
applicationServerKey ist der öffentliche VAPID-Schlüssel des Anwendungsservers als ArrayBuffer, oder null, wenn keiner angegeben wurde.Beispiele
Optionen eines bestehenden Abonnements auslesen
const registration = await navigator.serviceWorker.ready;
const subscription = await registration.pushManager.getSubscription();
if (subscription) {
const { userVisibleOnly, applicationServerKey } = subscription.options;
console.log('userVisibleOnly:', userVisibleOnly);
console.log('Schlüssellänge:', applicationServerKey?.byteLength);
}
Abonnement erneuern, wenn sich der VAPID-Schlüssel geändert hat
const VAPID_PUBLIC_KEY = 'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U';
// Base64url -> Uint8Array
const base64UrlToBytes = (str) => {
const padded = str.replace(/-/g, '+').replace(/_/g, '/') + '='.repeat((4 - (str.length % 4)) % 4);
return Uint8Array.from(atob(padded), (c) => c.charCodeAt(0));
};
const sameKey = (buffer, bytes) => {
if (!buffer) return false;
const a = new Uint8Array(buffer);
return a.length === bytes.length && a.every((v, i) => v === bytes[i]);
};
const ensureSubscription = async () => {
const registration = await navigator.serviceWorker.ready;
const expectedKey = base64UrlToBytes(VAPID_PUBLIC_KEY);
let sub = await registration.pushManager.getSubscription();
if (sub && !sameKey(sub.options.applicationServerKey, expectedKey)) {
console.log('Veralteter Schlüssel – Abonnement wird erneuert');
await sub.unsubscribe();
sub = null;
}
sub ??= await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: expectedKey,
});
return sub;
};
ensureSubscription().then((s) => console.log('Endpoint:', s.endpoint));
Schlüssel als Base64url an den Server melden
const bufferToBase64Url = (buf) =>
btoa(String.fromCharCode(...new Uint8Array(buf)))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
const registration = await navigator.serviceWorker.ready;
const sub = await registration.pushManager.getSubscription();
if (sub?.options.applicationServerKey) {
await fetch('/api/push/check', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
endpoint: sub.endpoint,
serverKey: bufferToBase64Url(sub.options.applicationServerKey),
}),
});
}
// Wichtig · Fallstricke
applicationServerKeyist immer einArrayBuffer. Ein direkter Vergleich mit===gegen einen String oder einUint8Arrayergibt daher immerfalse. Vergleiche die Werte deshalb Byte für Byte.- Die Eigenschaft ist schreibgeschützt. Um die Optionen zu ändern, kündigst du das Abonnement mit
unsubscribe()und legst es mitsubscribe()neu an. optionsist nicht Teil der Ausgabe vonPushSubscription.toJSON()und wird dadurch nicht automatisch an den Server übertragen.- Chrome und Safari verlangen
userVisibleOnly: true. Der Wert ist in der Praxis also fast immertrue. - Die Push-API funktioniert nur in sicheren Kontexten (HTTPS) und mit einem registrierten Service Worker. Safari unterstützt sie ab Version 16 (macOS) bzw. 16.4 (iOS, nur bei zum Home-Bildschirm hinzugefügten Web-Apps). Ältere Firefox-Versionen vor 75 kennen
optionsnoch nicht. Prüfe deshalb vor dem Zugriff, ob die Eigenschaft vorhanden ist.