Per inviare messaggi push, devi prima ottenere l'autorizzazione dell'utente e poi iscrivere il suo dispositivo a un servizio push. Ciò comporta l'utilizzo dell'API JavaScript per ottenere un oggetto PushSubscription, che poi invii al tuo server.
L'API JavaScript gestisce questo processo in modo semplice. Questa guida spiega l'intero flusso, tra cui il rilevamento delle funzionalità, la richiesta di autorizzazione e la gestione del processo di abbonamento.
Rilevamento delle caratteristiche
Innanzitutto, verifica se il browser supporta la messaggistica push. Puoi verificare se il push è supportato con due controlli:
- Controlla se è presente
serviceWorkernell'oggettonavigator. - Controlla se è presente
PushManagernell'oggettowindow.
if (!('serviceWorker' in navigator)) {
// Service Worker isn't supported on this browser, disable or hide UI.
return;
}
if (!('PushManager' in window)) {
// Push isn't supported on this browser, disable or hide UI.
return;
}
Sebbene il supporto dei browser sia per i service worker sia per la messaggistica push sia in aumento, rileva sempre entrambe le funzionalità e applica il potenziamento progressivo alla tua applicazione.
Registra un service worker
Dopo il rilevamento delle funzionalità, sai che i service worker e la messaggistica push sono supportati. Poi, registra il service worker.
Quando registri un service worker, indichi al browser la posizione del file del service worker. Il file è un file JavaScript, ma il browser gli concede l'accesso alle API dei service worker, inclusa la messaggistica push. Nello specifico, il browser esegue il file in un ambiente di service worker.
Per registrare un service worker, chiama navigator.serviceWorker.register() e passa il percorso al tuo file. Ad esempio:
function registerServiceWorker() {
return navigator.serviceWorker
.register('/service-worker.js')
.then(function (registration) {
console.log('Service worker successfully registered.');
return registration;
})
.catch(function (err) {
console.error('Unable to register service worker.', err);
});
}
Questa funzione indica al browser la posizione del file del service worker. In questo caso, il file del service worker si trova in /service-worker.js. Dopo aver chiamato register(), il browser esegue questi passaggi:
Scarica il file del service worker.
Esegui il codice JavaScript.
Se il file viene eseguito correttamente senza errori, la promise restituita da
register()viene risolta. Se si verificano errori, la promessa viene rifiutata.
Nota: se register() rifiuta, controlla il codice JavaScript per verificare che non siano presenti errori di battitura o altri errori in Chrome DevTools.
Quando register() viene risolto, restituisce un ServiceWorkerRegistration. Utilizza questa registrazione per accedere all'API PushManager.
Compatibilità del browser con l'API PushManager
Richiesta di autorizzazione
Dopo aver registrato il service worker e ottenuto l'autorizzazione, chiedi all'utente l'autorizzazione per inviare messaggi push.
L'API per ottenere l'autorizzazione è semplice. Tuttavia, l'API è stata recentemente modificata per restituire una Promise anziché accettare un callback. Poiché non puoi determinare quale versione dell'API viene implementata dal browser, devi implementare e gestire entrambe le versioni.
function askPermission() {
return new Promise(function (resolve, reject) {
const permissionResult = Notification.requestPermission(function (result) {
resolve(result);
});
if (permissionResult) {
permissionResult.then(resolve, reject);
}
}).then(function (permissionResult) {
if (permissionResult !== 'granted') {
throw new Error("We weren't granted permission.");
}
});
}
Nel codice precedente, la chiamata a Notification.requestPermission() mostra un prompt all'utente:

Dopo che l'utente ha interagito con la richiesta di autorizzazione selezionando Consenti, Blocca o chiudendola, ricevi il risultato sotto forma di stringa: 'granted', 'default' o 'denied'.
Nel codice campione, la promise restituita da askPermission() viene risolta se l'autorizzazione viene concessa; in caso contrario, genera un errore e la promise viene rifiutata.
Gestisci il caso limite in cui l'utente fa clic sul pulsante Blocca. In questo caso, l'app web non può chiedere di nuovo l'autorizzazione all'utente. L'utente deve sbloccare manualmente l'app modificando lo stato delle autorizzazioni in un riquadro delle impostazioni. Valuta attentamente quando e come chiedere l'autorizzazione, perché se un utente fa clic su Blocca, non è facile annullare la decisione.
La maggior parte degli utenti concede l'autorizzazione se comprende il motivo per cui l'app la richiede.
Questo documento spiega come alcuni siti popolari richiedono l'autorizzazione più avanti.
Iscrivere un utente con PushManager
Dopo aver registrato il service worker e ottenuto l'autorizzazione, puoi iscrivere un utente chiamando registration.pushManager.subscribe().
function subscribeUserToPush() {
return navigator.serviceWorker
.register('/service-worker.js')
.then(function (registration) {
const subscribeOptions = {
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(
'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
),
};
return registration.pushManager.subscribe(subscribeOptions);
})
.then(function (pushSubscription) {
console.log(
'Received PushSubscription: ',
JSON.stringify(pushSubscription),
);
return pushSubscription;
});
}
Quando chiami il metodo subscribe(), passi un oggetto options costituito da parametri obbligatori e facoltativi.
Questa sezione descrive le opzioni che puoi passare.
Opzioni userVisibleOnly
Quando la messaggistica push è stata aggiunta per la prima volta ai browser, gli sviluppatori non erano sicuri di inviare messaggi push senza mostrare una notifica. Questo tipo di notifica viene comunemente definito push silenzioso perché l'utente non sa che si è verificato un evento in background.
La preoccupazione era che gli sviluppatori potessero monitorare continuamente la posizione di un utente a sua insaputa.
Per evitare questo scenario e consentire agli autori delle specifiche di valutare il modo migliore per supportare questa funzionalità, è stata aggiunta l'opzione userVisibleOnly. Il passaggio di un valore di true è un accordo simbolico con il browser che l'app web mostra una notifica ogni volta che riceve un messaggio push (ovvero nessun push silenzioso).
Devi passare un valore di true. Se non includi la chiave userVisibleOnly o passi false, ricevi il seguente errore:
Chrome currently only supports the Push API for subscriptions that will result
in user-visible messages. You can indicate this by calling
`pushManager.subscribe({userVisibleOnly: true})` instead. See
[https://goo.gl/yqv4Q4](https://goo.gl/yqv4Q4) for more details.
Chrome supporta l'API Push solo per le iscrizioni che generano messaggi visibili all'utente. Indicalo chiamando pushManager.subscribe({userVisibleOnly: true}). Per saperne di più, visita la pagina https://goo.gl/yqv4Q4.
Sembra che il push silenzioso generale non verrà implementato in Chrome. Invece, gli autori delle specifiche stanno esplorando un'API di budget che consente alle app web di inviare un determinato numero di messaggi push silenziosi in base all'utilizzo dell'app web.
Opzione applicationServerKey
In precedenza, questo documento menzionava le chiavi del server dell'applicazione. Un servizio push utilizza le chiavi del server dell'applicazione per identificare l'applicazione che iscrive un utente e per garantire che la stessa applicazione invii messaggi all'utente.
Le chiavi del server dell'applicazione sono una coppia di chiavi pubblica e privata univoca per la tua applicazione. Mantieni la chiave privata segreta per la tua applicazione e condividi liberamente la chiave pubblica.
L'opzione applicationServerKey passata alla chiamata subscribe() è la chiave pubblica della tua applicazione. Il browser passa questa chiave a un servizio push quando l'utente si iscrive, consentendo al servizio push di collegare la chiave pubblica della tua applicazione all'PushSubscription dell'utente.
Il seguente diagramma illustra questi passaggi.
- Carica l'app web in un browser e chiama
subscribe(), passando la chiave del server dell'applicazione pubblica. - Il browser effettua quindi una richiesta di rete a un servizio push, che genera un endpoint, lo associa alla chiave pubblica della tua applicazione e lo restituisce al browser.
- Il browser aggiunge questo endpoint a
PushSubscription, che viene restituito dalla promisesubscribe().
Quando invii un messaggio push, crea un'intestazione Authorization che contenga informazioni firmate con la chiave privata del tuo server applicazioni. Quando il servizio push riceve una richiesta di invio di un messaggio push, convalida questa intestazione Authorization firmata cercando al volo la chiave pubblica collegata all'endpoint che riceve la richiesta. Se la firma è valida, il servizio push sa che la richiesta proviene dal server dell'applicazione con la chiave privata corrispondente. Si tratta di una misura di sicurezza che impedisce ad altri di inviare messaggi agli utenti della tua applicazione.
Tecnicamente, l'elemento applicationServerKey è facoltativo. Tuttavia, l'implementazione più semplice su Chrome lo richiede e altri browser potrebbero richiederlo in futuro. È facoltativo su Firefox.
La specifica VAPID definisce la chiave del server dell'applicazione. Quando vedi riferimenti alle chiavi del server dell'applicazione o alle chiavi VAPID, ricorda che sono la stessa cosa.
Crea chiavi del server applicazioni
Puoi creare un set pubblico e privato di chiavi del server applicazioni utilizzando la riga di comando web-push per generare le chiavi come segue:
$ npm install -g web-push
$ web-push generate-vapid-keys
Crea queste chiavi una sola volta per la tua applicazione e assicurati di mantenere privata la chiave privata.
Autorizzazioni e subscribe()
La chiamata di subscribe() ha un effetto collaterale. Se la tua app web non dispone dell'autorizzazione per mostrare le notifiche quando chiami subscribe(), il browser richiede le autorizzazioni per te. Questo è utile se la tua UI funziona con questo flusso, ma se vuoi un maggiore controllo (come la maggior parte degli sviluppatori), utilizza l'API Notification.requestPermission() discussa in precedenza in questo documento.
Panoramica di PushSubscription
Chiami subscribe(), passi le opzioni e ricevi una promise che si risolve in un PushSubscription. Ad esempio:
function subscribeUserToPush() {
return navigator.serviceWorker
.register('/service-worker.js')
.then(function (registration) {
const subscribeOptions = {
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(
'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
),
};
return registration.pushManager.subscribe(subscribeOptions);
})
.then(function (pushSubscription) {
console.log(
'Received PushSubscription: ',
JSON.stringify(pushSubscription),
);
return pushSubscription;
});
}
L'oggetto PushSubscription contiene tutte le informazioni necessarie per inviare messaggi push all'utente. Se stampi i contenuti utilizzando JSON.stringify(), viene visualizzato quanto segue:
{
"endpoint": "https://some.pushservice.com/something-unique",
"keys": {
"p256dh":
"BIPUL12DLfytvTajnryr2PRdAgXS3HGKiLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WAkAPIxr4gK0_dQds4yiI=",
"auth":"FPssNDTKnInHVndSTdbKFw=="
}
}
endpoint è l'URL del servizio push. Per attivare un messaggio push, invia una richiesta POST a questo URL.
L'oggetto keys contiene i valori utilizzati per criptare i dati dei messaggi inviati con un messaggio push. (Questo documento tratta la crittografia dei messaggi più avanti).
Invia un abbonamento al tuo server
Una volta ottenuta una sottoscrizione push, inviala al tuo server. Sei tu a decidere come inviarla, ma un suggerimento è utilizzare JSON.stringify() per estrarre tutti i dati necessari dall'oggetto dell'abbonamento. In alternativa, puoi assemblare manualmente lo stesso risultato, ad esempio:
const subscriptionObject = {
endpoint: pushSubscription.endpoint,
keys: {
p256dh: pushSubscription.getKeys('p256dh'),
auth: pushSubscription.getKeys('auth'),
},
};
// The above is the same output as:
const subscriptionObjectToo = JSON.stringify(pushSubscription);
Per inviare l'abbonamento dalla pagina web, utilizza quanto segue:
function sendSubscriptionToBackEnd(subscription) {
return fetch('/api/save-subscription/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(subscription),
})
.then(function (response) {
if (!response.ok) {
throw new Error('Bad status code from server.');
}
return response.json();
})
.then(function (responseData) {
if (!(responseData.data && responseData.data.success)) {
throw new Error('Bad response from server.');
}
});
}
Il server Node.js riceve questa richiesta e salva i dati in un database per un utilizzo successivo.
app.post('/api/save-subscription/', function (req, res) {
if (!isValidSaveRequest(req, res)) {
return;
}
return saveSubscriptionToDatabase(req.body)
.then(function (subscriptionId) {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({data: {success: true}}));
})
.catch(function (err) {
res.status(500);
res.setHeader('Content-Type', 'application/json');
res.send(
JSON.stringify({
error: {
id: 'unable-to-save-subscription',
message:
'The subscription was received but we were unable to save it to our database.',
},
}),
);
});
});
Con i dettagli di PushSubscription sul tuo server, puoi inviare un messaggio all'utente in qualsiasi momento.
Riabbonati regolarmente per evitare la scadenza
Quando ti iscrivi alle notifiche push, spesso ricevi un PushSubscription.expirationTime di null. In teoria, ciò significa che l'abbonamento non scade mai. (Al contrario, un DOMHighResTimeStamp indica l'ora esatta di scadenza). In pratica, però, i browser di solito lasciano scadere le iscrizioni. Ad esempio, ciò può accadere se non vengono ricevute notifiche push per un lungo periodo di tempo o se il browser rileva che l'utente non utilizza un'app che dispone dell'autorizzazione alle notifiche push. Un pattern per evitare questo problema è iscrivere nuovamente l'utente a ogni notifica ricevuta, come mostrato nello snippet seguente. Ciò richiede l'invio di notifiche con una frequenza sufficiente per impedire al browser di far scadere automaticamente l'iscrizione. Devi valutare attentamente i vantaggi e gli svantaggi delle esigenze di notifica legittime rispetto allo spam involontario dell'utente al solo scopo di impedire la scadenza dell'abbonamento. In definitiva, non dovresti cercare di aggirare gli sforzi del browser per proteggere l'utente da iscrizioni alle notifiche dimenticate da tempo.
/* In the Service Worker. */
self.addEventListener('push', function(event) {
console.log('Received a push message', event);
// Display notification or handle data
// Example: show a notification
const title = 'New Notification';
const body = 'You have new updates!';
const icon = '/images/icon.png';
const tag = 'simple-push-demo-notification-tag';
event.waitUntil(
self.registration.showNotification(title, {
body: body,
icon: icon,
tag: tag
})
);
// Attempt to resubscribe after receiving a notification
event.waitUntil(resubscribeToPush());
});
function resubscribeToPush() {
return self.registration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
return subscription.unsubscribe();
}
})
.then(function() {
return self.registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array('YOUR_PUBLIC_VAPID_KEY_HERE')
});
})
.then(function(subscription) {
console.log('Resubscribed to push notifications:', subscription);
// Optionally, send new subscription details to your server
})
.catch(function(error) {
console.error('Failed to resubscribe:', error);
});
}
Domande frequenti
Ecco alcune domande comuni:
È possibile modificare il servizio push utilizzato da un browser?
No, il browser seleziona il servizio push. Come spiegato in questo documento in relazione alla chiamata subscribe(), il browser effettua richieste di rete al servizio push per recuperare i dettagli che compongono l'oggetto PushSubscription.
I diversi servizi push utilizzano API diverse?
Tutti i servizi push prevedono la stessa API.
Questa API comune, chiamata protocollo Web Push, descrive la richiesta di rete effettuata dalla tua applicazione per attivare un messaggio push.
Se iscrivi un utente sul suo computer, l'iscrizione è valida anche sul suo smartphone?
No. Un utente deve registrarsi alla messaggistica push su ogni browser su cui vuole ricevere i messaggi. Inoltre, l'utente deve concedere l'autorizzazione su ogni dispositivo.
Passaggi successivi
- Panoramica delle notifiche push web
- Come funzionano i messaggi push
- Iscrivi un utente
- Esperienza utente relativa alle autorizzazioni
- Invia messaggi con le librerie di push web
- Protocollo Web Push
- Gestisci gli eventi push
- Visualizza una notifica
- Comportamento delle notifiche
- Pattern di notifica comuni
- Domande frequenti sulle notifiche push
- Problemi comuni e segnalazione di bug