Pour envoyer des messages push, vous devez d'abord obtenir l'autorisation de l'utilisateur, puis abonner son appareil à un service push. Pour ce faire, vous devez utiliser l'API JavaScript afin d'obtenir un objet PushSubscription, que vous enverrez ensuite à votre serveur.
L'API JavaScript gère ce processus de manière simple. Ce guide explique l'intégralité du flux, y compris la détection des fonctionnalités, la demande d'autorisation et la gestion du processus d'abonnement.
Détection des fonctionnalités
Tout d'abord, vérifiez si le navigateur est compatible avec les messages push. Pour vérifier si les notifications push sont prises en charge, vous pouvez effectuer deux vérifications :
- Recherchez
serviceWorkersur l'objetnavigator. - Recherchez
PushManagersur l'objetwindow.
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;
}
Bien que la prise en charge des service workers et des messages push par les navigateurs augmente, détectez toujours les deux fonctionnalités et améliorez progressivement votre application.
Enregistrer un service worker
Après la détection des fonctionnalités, vous savez que les service workers et la messagerie push sont compatibles. Ensuite, enregistrez votre service worker.
Lorsque vous enregistrez un service worker, vous indiquez au navigateur l'emplacement de votre fichier service worker. Le fichier est un fichier JavaScript, mais le navigateur lui accorde l'accès aux API Service Worker, y compris la messagerie push. Plus précisément, le navigateur exécute le fichier dans un environnement de service worker.
Pour enregistrer un service worker, appelez navigator.serviceWorker.register() et transmettez le chemin d'accès à votre fichier. Exemple :
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);
});
}
Cette fonction indique au navigateur l'emplacement de votre fichier Service Worker. Ici, le fichier du service worker se trouve à l'adresse /service-worker.js. Après avoir appelé register(), le navigateur effectue les étapes suivantes :
Téléchargez le fichier du service worker.
Exécutez le code JavaScript.
Si le fichier s'exécute correctement sans erreur, la promesse renvoyée par
register()est résolue. Si des erreurs se produisent, la promesse est rejetée.
Remarque : Si register() est refusé, vérifiez que votre code JavaScript ne comporte pas de fautes de frappe ni d'erreurs dans les outils pour les développeurs Chrome.
Lorsque register() est résolu, il renvoie un ServiceWorkerRegistration. Vous utilisez cet enregistrement pour accéder à l'API PushManager.
Compatibilité du navigateur avec l'API PushManager
Demander l'autorisation
Après avoir enregistré votre service worker et obtenu l'autorisation, demandez à l'utilisateur l'autorisation d'envoyer des messages push.
L'API permettant d'obtenir l'autorisation est simple. Toutefois, l'API a récemment changé et renvoie désormais une promesse au lieu d'un rappel. Comme vous ne pouvez pas déterminer quelle version de l'API le navigateur implémente, vous devez implémenter et gérer les deux versions.
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.");
}
});
}
Dans le code précédent, l'appel à Notification.requestPermission() affiche une invite à l'utilisateur :

Une fois que l'utilisateur a interagi avec l'invite d'autorisation en sélectionnant Autoriser, Bloquer ou en la fermant, vous recevez le résultat sous forme de chaîne : 'granted', 'default' ou 'denied'.
Dans l'exemple de code, la promesse renvoyée par askPermission() est résolue si l'autorisation est accordée. Sinon, elle génère une erreur et la promesse est rejetée.
Gérez le cas limite où l'utilisateur clique sur le bouton Bloquer. Dans ce cas, votre application Web ne peut plus demander l'autorisation à l'utilisateur. L'utilisateur doit débloquer manuellement votre application en modifiant son état d'autorisation dans un panneau de paramètres. Réfléchissez bien au moment et à la manière de demander l'autorisation, car si un utilisateur clique sur Bloquer, il ne pourra pas revenir facilement sur sa décision.
La plupart des utilisateurs accordent l'autorisation s'ils comprennent pourquoi l'application la demande.
Ce document explique comment certains sites populaires demandent l'autorisation plus loin dans ce document.
Abonner un utilisateur avec PushManager
Après avoir enregistré votre service worker et obtenu l'autorisation, vous pouvez abonner un utilisateur en appelant 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;
});
}
Lorsque vous appelez la méthode subscribe(), vous transmettez un objet options qui se compose de paramètres obligatoires et facultatifs.
Cette section décrit les options que vous pouvez transmettre.
Options userVisibleOnly
Lorsque la messagerie push a été ajoutée aux navigateurs, les développeurs n'étaient pas sûrs de pouvoir envoyer des messages push sans afficher de notification. On parle généralement de notification push silencieuse, car l'utilisateur n'est pas informé qu'un événement s'est produit en arrière-plan.
La crainte était que les développeurs puissent suivre la position d'un utilisateur en continu à son insu.
Pour éviter ce scénario et permettre aux auteurs de spécifications de réfléchir à la meilleure façon de prendre en charge cette fonctionnalité, l'option userVisibleOnly a été ajoutée. Transmettre une valeur de true est un accord symbolique avec le navigateur indiquant que l'application Web affiche une notification chaque fois qu'elle reçoit un message push (c'est-à-dire sans push silencieux).
Vous devez transmettre une valeur de true. Si vous n'incluez pas la clé userVisibleOnly ou le pass false, l'erreur suivante s'affiche :
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 n'est compatible avec l'API Push que pour les abonnements qui génèrent des messages visibles par l'utilisateur. Pour ce faire, appelez pushManager.subscribe({userVisibleOnly: true}). Pour en savoir plus, consultez https://goo.gl/yqv4Q4.
Il semble que le push silencieux général ne sera pas implémenté dans Chrome. Les auteurs de spécifications explorent plutôt une API de budget qui permet aux applications Web d'envoyer un certain nombre de messages push silencieux en fonction de l'utilisation de l'application Web.
Option applicationServerKey
Ce document mentionnait auparavant les clés du serveur d'application. Un service de notification push utilise des clés de serveur d'application pour identifier l'application qui abonne un utilisateur et s'assurer que la même application lui envoie des messages.
Les clés du serveur d'application sont une paire de clés publique et privée propre à votre application. Conservez la clé privée secrète pour votre application et partagez la clé publique librement.
L'option applicationServerKey transmise à l'appel subscribe() correspond à la clé publique de votre application. Le navigateur transmet cette clé à un service de notification push lors de l'abonnement de l'utilisateur, ce qui permet au service de notification push d'associer la clé publique de votre application au PushSubscription de l'utilisateur.
Le schéma suivant illustre ces étapes.
- Chargez votre application Web dans un navigateur et appelez
subscribe()en transmettant la clé publique de votre serveur d'application. - Le navigateur envoie ensuite une requête réseau à un service de notification push, qui génère un point de terminaison, l'associe à la clé publique de votre application et renvoie le point de terminaison au navigateur.
- Le navigateur ajoute ce point de terminaison à
PushSubscription, que renvoie la promessesubscribe().
Lorsque vous envoyez un message push, créez un en-tête Authorization contenant des informations signées avec la clé privée de votre serveur d'application. Lorsque le service de notification push reçoit une requête d'envoi d'un message push, il valide cet en-tête Authorization signé en recherchant la clé publique associée au point de terminaison qui reçoit la requête. Si la signature est valide, le service de notification push sait que la requête provient du serveur d'application avec la clé privée correspondante. Il s'agit d'une mesure de sécurité qui empêche les tiers d'envoyer des messages aux utilisateurs de votre application.
Techniquement, l'élément applicationServerKey est facultatif. Toutefois, l'implémentation la plus simple sur Chrome l'exige, et d'autres navigateurs pourraient l'exiger à l'avenir. Il est facultatif sur Firefox.
La spécification VAPID définit la clé du serveur d'application. Lorsque vous voyez des références à des clés de serveur d'application ou à des clés VAPID, n'oubliez pas qu'il s'agit de la même chose.
Créer des clés de serveur d'application
Vous pouvez créer un ensemble public et privé de clés de serveur d'application en accédant à web-push-codelab.glitch.me ou en utilisant la ligne de commande web-push pour générer des clés comme suit :
$ npm install -g web-push
$ web-push generate-vapid-keys
Créez ces clés une seule fois pour votre application et assurez-vous de garder la clé privée confidentielle.
Autorisations et subscribe()
L'appel de subscribe() a un effet secondaire. Si votre application Web n'est pas autorisée à afficher des notifications lorsque vous appelez subscribe(), le navigateur demande les autorisations pour vous. Cette méthode est utile si votre UI fonctionne avec ce flux. Toutefois, si vous souhaitez davantage de contrôle (ce qui est le cas de la plupart des développeurs), utilisez l'API Notification.requestPermission() dont il a été question plus haut dans ce document.
Présentation de PushSubscription
Vous appelez subscribe(), transmettez des options et recevez une promesse qui se résout en PushSubscription. Exemple :
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'objet PushSubscription contient toutes les informations nécessaires pour envoyer des messages push à cet utilisateur. Si vous affichez le contenu à l'aide de JSON.stringify(), vous verrez ce qui suit :
{
"endpoint": "https://some.pushservice.com/something-unique",
"keys": {
"p256dh":
"BIPUL12DLfytvTajnryr2PRdAgXS3HGKiLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WAkAPIxr4gK0_dQds4yiI=",
"auth":"FPssNDTKnInHVndSTdbKFw=="
}
}
endpoint correspond à l'URL du service de notification push. Pour déclencher un message push, envoyez une requête POST à cette URL.
L'objet keys contient les valeurs utilisées pour chiffrer les données de message envoyées avec un message push. (Le chiffrement des messages sera abordé plus loin dans ce document.)
Envoyer un abonnement à votre serveur
Une fois que vous avez un abonnement push, envoyez-le à votre serveur. Vous déterminez comment l'envoyer, mais nous vous conseillons d'utiliser JSON.stringify() pour extraire toutes les données nécessaires de l'objet d'abonnement. Vous pouvez également assembler manuellement le même résultat, par exemple :
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);
Pour envoyer l'abonnement depuis la page Web, utilisez ce qui suit :
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.');
}
});
}
Le serveur Node.js reçoit cette requête et enregistre les données dans une base de données pour une utilisation ultérieure.
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.',
},
}),
);
});
});
Grâce aux informations PushSubscription sur votre serveur, vous pouvez envoyer un message à votre utilisateur à tout moment.
Se réabonner régulièrement pour éviter l'expiration
Lorsque vous vous abonnez aux notifications push, vous recevez souvent un PushSubscription.expirationTime de null. En théorie, cela signifie que l'abonnement n'expire jamais. (En revanche, DOMHighResTimeStamp indique l'heure d'expiration exacte.) Cependant, dans la pratique, les navigateurs laissent généralement les abonnements expirer. Par exemple, cela peut se produire si aucune notification push n'est reçue pendant une longue période ou si le navigateur détecte que l'utilisateur n'utilise pas une application disposant de l'autorisation d'envoyer des notifications push. Pour éviter cela, vous pouvez réabonner l'utilisateur à chaque notification reçue, comme le montre l'extrait suivant. Pour cela, vous devez envoyer des notifications suffisamment souvent pour empêcher le navigateur de faire expirer automatiquement l'abonnement. Vous devez examiner attentivement les avantages et les inconvénients des besoins de notification légitimes par rapport à l'envoi involontaire de spams à l'utilisateur uniquement pour éviter l'expiration de l'abonnement. En fin de compte, vous ne devez pas essayer de contourner les efforts du navigateur pour protéger l'utilisateur des abonnements aux notifications oubliés depuis longtemps.
/* 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);
});
}
Questions fréquentes
Voici quelques questions fréquentes :
Peut-on modifier le service de notification push utilisé par un navigateur ?
Non, c'est le navigateur qui sélectionne le service de notification push. Comme indiqué dans ce document avec l'appel subscribe(), le navigateur envoie des requêtes réseau au service de notification push pour récupérer les détails qui composent PushSubscription.
Les différents services de notification push utilisent-ils des API différentes ?
Tous les services push s'attendent à la même API.
Cette API commune, appelée Web Push Protocol, décrit la requête réseau que votre application envoie pour déclencher un message push.
Si vous abonnez un utilisateur sur son ordinateur, est-il également abonné sur son téléphone ?
Non. Un utilisateur doit s'inscrire aux messages push sur chaque navigateur sur lequel il souhaite les recevoir. L'utilisateur doit également accorder l'autorisation sur chaque appareil.
Étapes suivantes
- Présentation des notifications push Web
- Fonctionnement des messages push
- Abonner un utilisateur
- Expérience utilisateur concernant les autorisations
- Envoyer des messages avec des bibliothèques de notifications push Web
- Protocole Web Push
- Gérer les événements push
- Afficher une notification
- Comportement des notifications
- Schémas de notification courants
- Questions fréquentes sur les notifications push
- Problèmes courants et bugs liés aux rapports