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 pour obtenir un objet PushSubscription, que vous envoyez ensuite à votre serveur.
L'API JavaScript gère ce processus de manière simple. Ce guide explique l'ensemble du processus, y compris la détection des fonctionnalités, la demande d'autorisation et la gestion du processus d'abonnement.
Détection de caractéristiques
Tout d'abord, vérifiez si le navigateur est compatible avec la messagerie push. Vous pouvez vérifier la compatibilité avec le push de deux manières :
- 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 compatibilité des navigateurs avec les service workers et les messages push soit de plus en plus répandue, détectez toujours ces 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 de service worker. Il s'agit d'un fichier JavaScript, mais le navigateur lui accorde l'accès aux API de 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 de service worker. Ici, le fichier du service worker se trouve dans /service-worker.js. Une fois que vous avez 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 rejeté, vérifiez que votre code JavaScript ne contient 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é de l'API PushManager avec les navigateurs
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 été modifiée pour renvoyer 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 particulier 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 n'est pas facile de revenir sur cette 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 composé 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 "push silencieux", car l'utilisateur ne sait pas qu'un événement s'est produit en arrière-plan.
Le problème était que les développeurs pouvaient 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. La transmission d'une valeur true est un accord symbolique avec le navigateur selon lequel l'application Web affiche une notification chaque fois qu'elle reçoit un message push (c'est-à-dire pas de push silencieux).
Vous devez transmettre une valeur true. Si vous n'incluez pas la clé userVisibleOnly ou si vous transmettez false, vous recevez l'erreur suivante :
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. Indiquez-le en appelant pushManager.subscribe({userVisibleOnly: true}). Pour en savoir plus, consultez https://goo.gl/yqv4Q4.
Il semble que les notifications push silencieuses générales ne seront pas implémentées dans Chrome. À la place, les auteurs de la spécification explorent 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 de serveur d'application. Un service 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 envoie des messages à cet utilisateur.
Les clés de serveur d'application sont une paire de clés publique et privée unique pour votre application. Gardez la clé privée secrète pour votre application et partagez librement la clé publique.
L'option applicationServerKey transmise à l'appel subscribe() est la clé publique de votre application. Le navigateur transmet cette clé à un service push lors de l'abonnement de l'utilisateur, ce qui permet au service 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 votre clé de serveur d'application publique. - Le navigateur envoie ensuite une requête réseau à un service push, qui génère un point de terminaison, l'associe à la clé publique de votre application et le renvoie au navigateur.
- Le navigateur ajoute ce point de terminaison à l'objet
PushSubscription, qui est renvoyé par 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'applications. Lorsque le service 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 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 d'autres personnes d'envoyer des messages aux utilisateurs de votre application.
Techniquement, l'élément applicationServerKey est facultatif. Cependant, 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 de clés de serveur d'application publiques et privées à l'aide de 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 veillez à ce que la clé privée reste privée.
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 approche est utile si votre UI fonctionne avec ce flux, mais si vous souhaitez plus de contrôle (ce que la plupart des développeurs souhaitent), utilisez l'API Notification.requestPermission() dont nous avons parlé plus tôt dans ce document.
Présentation de PushSubscription
Vous appelez subscribe(), transmettez des options et recevez une promesse qui se résout en un 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 imprimez le contenu à l'aide de JSON.stringify(), vous obtenez le résultat suivant :
{
"endpoint": "https://some.pushservice.com/something-unique",
"keys": {
"p256dh":
"BIPUL12DLfytvTajnryr2PRdAgXS3HGKiLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WAkAPIxr4gK0_dQds4yiI=",
"auth":"FPssNDTKnInHVndSTdbKFw=="
}
}
endpoint est l'URL du service 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. (Ce document traite du chiffrement des messages plus loin.)
Envoyer un abonnement à votre serveur
Une fois que vous disposez d'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 la commande suivante :
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, un DOMHighResTimeStamp indique l'heure d'expiration exacte.) En pratique, toutefois, 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 d'application disposant de l'autorisation d'envoyer des notifications push. Pour éviter cela, vous pouvez réabonner l'utilisateur à chaque notification reçue, comme illustré dans l'extrait suivant. Pour cela, vous devez envoyer des notifications suffisamment souvent pour éviter que le navigateur n'expire automatiquement l'abonnement. Vous devez peser soigneusement le pour et le contre entre les besoins légitimes de notification et le risque de spammer involontairement 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 courantes :
Pouvez-vous modifier le service push utilisé par un navigateur ?
Non, le navigateur sélectionne le service push. Comme indiqué dans ce document avec l'appel subscribe(), le navigateur envoie des requêtes réseau au service push pour récupérer les détails qui composent l'objet PushSubscription.
Les différents services push utilisent-ils des API différentes ?
Tous les services push attendent la même API.
Cette API commune, appelée protocole Web Push, décrit la requête réseau que votre application effectue 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 à la messagerie push sur chaque navigateur où il souhaite recevoir des messages. Cela nécessite également que l'utilisateur accorde l'autorisation sur chaque appareil.
Étapes suivantes
- Présentation des notifications push Web
- Fonctionnement de la messagerie push
- Abonner un utilisateur
- Expérience utilisateur liée aux 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
- Modèles de notification courants
- Questions fréquentes sur les notifications push
- Problèmes courants et signalement de bugs