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 questa procedura in modo semplice. Questa guida spiega l'intero flusso, inclusi il rilevamento delle funzionalità, la richiesta di autorizzazione e la gestione della procedura di abbonamento.
Rilevamento delle funzionalità
Innanzitutto, verifica se il browser supporta i messaggi push. Puoi verificare il supporto delle notifiche push in due modi:
- Controlla la presenza di
serviceWorkernell'oggettonavigator. - Controlla la presenza di
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 del browser per service worker e messaggistica push sia in aumento, rileva sempre entrambe le funzionalità e migliora progressivamente la tua applicazione.
Registrare un service worker
Dopo il rilevamento delle funzionalità, sai che i service worker e la messaggistica push sono supportati. Successivamente, registra il service worker.
Quando registri un service worker, comunichi al browser la posizione del file del service worker. Il file è un file JavaScript, ma il browser gli concede l'accesso alle API service worker, inclusi i messaggi push. Nello specifico, il browser esegue il file in un ambiente service worker.
Per registrare un service worker, chiama navigator.serviceWorker.register() e passa il percorso del 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 service worker. In questo caso, il file service worker si trova in /service-worker.js. Dopo aver chiamato register(), il browser esegue questi passaggi:
Scarica il file del service worker.
Esegui JavaScript.
Se il file viene eseguito correttamente senza errori, la promessa restituita da
register()viene risolta. Se si verificano errori, la promessa viene rifiutata.
Nota: se register() rifiuta, controlla che non ci siano errori di battitura o errori nel codice JavaScript in Chrome DevTools.
Quando register() viene risolto, restituisce un ServiceWorkerRegistration. Utilizzi 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 il permesso di inviare messaggi push.
L'API per ottenere l'autorizzazione è semplice. Tuttavia, l'API di recente è passata dall'accettazione di un callback alla restituzione di una promessa. Poiché non puoi determinare quale versione dell'API implementa il 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 all'utente una richiesta:

Dopo che l'utente interagisce con la richiesta di autorizzazione selezionando Consenti, Blocca o chiudendola, ricevi il risultato come stringa: 'granted', 'default' o 'denied'.
Nel codice di esempio, la promessa restituita da askPermission() viene risolta se viene concessa l'autorizzazione; in caso contrario, genera un errore e la promessa viene rifiutata.
Gestisci il caso limite in cui l'utente fa clic sul pulsante Blocca. In questo caso, l'app web non può chiedere nuovamente l'autorizzazione all'utente. L'utente deve sbloccare manualmente la tua app modificandone lo stato dell'autorizzazione in un pannello 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 capisce perché 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 trasmettere.
Opzioni userVisibleOnly
Quando è stata aggiunta per la prima volta la messaggistica push ai browser, gli sviluppatori non erano sicuri di inviare messaggi push senza visualizzare una notifica. Questo processo è comunemente chiamato push silenzioso perché l'utente non sa che si è verificato un evento in background.
Il problema era che gli sviluppatori potevano 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. L'invio di un valore true è un accordo simbolico con il browser in base al quale 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 la password 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 gli abbonamenti che generano messaggi visibili all'utente. Indicalo chiamando il numero pushManager.subscribe({userVisibleOnly: true}). Per ulteriori informazioni, visita la pagina https://goo.gl/yqv4Q4.
Sembra che il push silenzioso generale non verrà implementato in Chrome. Gli autori delle specifiche stanno invece esplorando un'API di budget che consente alle app web di inviare un determinato numero di notifiche push silenziose in base all'utilizzo dell'app web.
Opzione applicationServerKey
In precedenza, questo documento menzionava le chiavi del server delle applicazioni. Un servizio push utilizza le chiavi del server delle applicazioni per identificare l'applicazione che iscrive un utente e per garantire che l'utente riceva messaggi dalla stessa applicazione.
Le chiavi del server delle applicazioni sono una coppia di chiavi pubblica e privata univoca per la tua applicazione. Tieni segreta la chiave privata 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 al momento della registrazione dell'utente, il che consente al servizio push di collegare la chiave pubblica della tua applicazione al PushSubscription dell'utente.
Il seguente diagramma illustra questi passaggi.
- Carica la tua app web in un browser e chiama
subscribe(), passando la chiave del server delle applicazioni pubblico. - Il browser effettua quindi una richiesta di rete a un servizio push, che genera un endpoint, lo associa alla chiave pubblica dell'applicazione e lo restituisce al browser.
- Il browser aggiunge questo endpoint a
PushSubscription, che viene restituito dalla promessasubscribe().
Quando invii un messaggio push, crea un'intestazione Authorization che contenga informazioni firmate con la chiave privata del server delle applicazioni. Quando il servizio push riceve una richiesta di invio di un messaggio push, convalida questa intestazione Authorization firmata cercando la chiave pubblica collegata all'endpoint che riceve la richiesta. Se la firma è valida, il servizio push sa che la richiesta proviene dal server delle applicazioni 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, 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 delle applicazioni. Quando vedi riferimenti a chiavi del server delle applicazioni o chiavi VAPID, ricorda che sono la stessa cosa.
Crea le chiavi del server delle applicazioni
Puoi creare un insieme pubblico e privato di chiavi del server delle applicazioni visitando web-push-codelab.glitch.me o utilizzando la riga di comando web-push per generare le chiavi nel seguente modo:
$ 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 a 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 tuo conto. Questa opzione è 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() di cui abbiamo parlato in precedenza in questo documento.
Panoramica di PushSubscription
Chiami subscribe(), passi le opzioni e ricevi una promessa 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(), visualizzi 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.
Inviare un abbonamento al server
Una volta ottenuto un abbonamento push, invialo al tuo server. Sei tu a decidere come inviarlo, ma un suggerimento è quello di utilizzare JSON.stringify() per estrarre tutti i dati necessari dall'oggetto della sottoscrizione. 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 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. Tuttavia, in pratica, i browser lasciano scadere gli abbonamenti. Ad esempio, questo può verificarsi 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 per le notifiche push. Un pattern per evitare questo problema è quello di iscrivere nuovamente l'utente a ogni notifica ricevuta, come mostrato nel seguente snippet. Ciò richiede l'invio di notifiche con una frequenza sufficiente a impedire la scadenza automatica dell'iscrizione da parte del browser. Devi valutare attentamente i vantaggi e gli svantaggi delle esigenze di notifica legittime rispetto all'invio involontario di spam all'utente al solo scopo di impedire la scadenza dell'abbonamento. In definitiva, non devi tentare di aggirare gli sforzi del browser per proteggere l'utente da abbonamenti alle notifiche dimenticati 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 discusso in questo documento durante la chiamata subscribe(), il browser effettua richieste di rete al servizio push per recuperare i dettagli che compongono PushSubscription.
Servizi push diversi utilizzano API diverse?
Tutti i servizi push si aspettano la stessa API.
Questa API comune, chiamata Web Push Protocol, descrive la richiesta di rete che la tua applicazione effettua per attivare un messaggio push.
Se iscrivo un utente sul computer, l'iscrizione viene applicata anche al suo smartphone?
No. Un utente deve registrarsi per la messaggistica push su ogni browser su cui vuole ricevere messaggi. Inoltre, l'utente deve concedere l'autorizzazione su ogni dispositivo.
Passaggi successivi
- Panoramica delle notifiche web push
- Come funziona la messaggistica push
- Abbonarsi a un utente
- Esperienza utente relativa alle autorizzazioni
- Inviare messaggi con le librerie push web
- Web Push Protocol
- Gestire gli eventi push
- Visualizzare una notifica
- Comportamento delle notifiche
- Pattern di notifica comuni
- Domande frequenti sulle notifiche push
- Problemi comuni e segnalazione di bug