Signatur
Beschreibung
permissionState() fragt ab, ob die Seite Push-Nachrichten empfangen darf. Die Methode wird auf dem PushManager einer Service-Worker-Registrierung aufgerufen (registration.pushManager). Sie fragt den Nutzer nicht um Erlaubnis, sondern gibt nur den aktuellen Status zurück.
Mögliche Werte:
"granted": Der Nutzer hat Push erlaubt.subscribe()klappt ohne Rückfrage."denied": Der Nutzer hat Push abgelehnt.subscribe()schlägt fehl."prompt": Es gibt noch keine Entscheidung. Beim erstensubscribe()erscheint ein Berechtigungsdialog.
Typischer Einsatz: Man prüft vor dem Anmelden, welche Oberfläche man zeigt, etwa einen „Benachrichtigungen aktivieren“-Button, einen Hinweis bei gesperrter Berechtigung oder gar nichts, wenn schon ein Abo besteht. Das options-Objekt sollte zu den Optionen passen, die man später an subscribe() übergibt, vor allem userVisibleOnly: true. Einige Browser werten den Status abhängig von diesen Optionen aus.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $options | Object | {} | Optionales Objekt mit den gleichen Feldern wie bei PushManager.subscribe(): userVisibleOnly (boolean, gibt an, ob jede Push-Nachricht eine sichtbare Benachrichtigung auslöst) und applicationServerKey (string | ArrayBuffer | TypedArray, öffentlicher VAPID-Schlüssel). |
Rückgabewert
NotSupportedError), wenn der Browser die Optionen nicht unterstützt, etwa userVisibleOnly: false in Chrome.Beispiele
Berechtigungsstatus einfach abfragen
const registration = await navigator.serviceWorker.ready;
const state = await registration.pushManager.permissionState({
userVisibleOnly: true
});
console.log(`Push-Berechtigung: ${state}`);
Oberfläche abhängig vom Status anzeigen
const pushButton = document.querySelector('#push-aktivieren');
const hinweis = document.querySelector('#push-hinweis');
const initPushUI = async () => {
if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
hinweis.textContent = 'Push wird von diesem Browser nicht unterstützt.';
return;
}
const registration = await navigator.serviceWorker.register('/sw.js');
const state = await registration.pushManager.permissionState({ userVisibleOnly: true });
switch (state) {
case 'granted': {
const sub = await registration.pushManager.getSubscription();
pushButton.hidden = Boolean(sub); // schon abonniert → Button ausblenden
break;
}
case 'prompt':
pushButton.hidden = false;
break;
case 'denied':
pushButton.hidden = true;
hinweis.textContent = 'Benachrichtigungen sind blockiert. Bitte in den Browser-Einstellungen freigeben.';
break;
}
};
initPushUI();
Nur abonnieren, wenn nicht blockiert (mit VAPID-Schlüssel)
const VAPID_PUBLIC_KEY = 'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U';
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 subscribeIfAllowed = async () => {
const registration = await navigator.serviceWorker.ready;
const options = {
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
};
const state = await registration.pushManager.permissionState(options);
if (state === 'denied') {
console.warn('Push blockiert – kein Abo möglich.');
return null;
}
// Bei "prompt" erscheint jetzt der Browser-Dialog
const subscription = await registration.pushManager.subscribe(options);
await fetch('/api/push/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(subscription)
});
return subscription;
};
// Nur nach einer Nutzeraktion aufrufen, z. B. per Klick
document.querySelector('#push-aktivieren')
.addEventListener('click', subscribeIfAllowed);
// Wichtig · Fallstricke
- Kein Berechtigungsdialog:
permissionState()fragt nur ab. Die eigentliche Anfrage stelltsubscribe()oderNotification.requestPermission(), und zwar nur nach einer Nutzeraktion wie einem Klick. Sonst blockieren viele Browser den Dialog oder zeigen ihn nur verkleinert an. - Sicherer Kontext nötig: Die Methode gibt es nur über HTTPS (oder
localhost) und nur mit einem registrierten Service Worker. userVisibleOnly: Chrome verlangtuserVisibleOnly: true. Ohne diese Option kann das Promise mitNotSupportedErrorabgelehnt werden. Am besten übergibt man immer dieselben Optionen wie beisubscribe().- Safari/iOS: Auf iOS und iPadOS gibt es Web Push erst ab 16.4 und nur für Web-Apps, die zum Home-Bildschirm hinzugefügt wurden. Im normalen Safari-Tab fehlt
PushManager. Deshalb vorher die Unterstützung prüfen ('PushManager' in window). - Alternative:
navigator.permissions.query({ name: 'push', userVisibleOnly: true })liefert den gleichen Status alsPermissionStatus. Dieses Objekt meldet mit demchange-Event auch spätere Änderungen. Firefox unterstützt den Namen'push'dort aber nicht in allen Versionen. - Der Status
"granted"bedeutet nicht, dass schon ein Abo besteht. Das prüft man mitgetSubscription().