La première étape consiste à demander à l'utilisateur
l'autorisation de lui envoyer des messages push.
mettre la main sur un PushSubscription
.
Pour ce faire, l'API JavaScript est relativement simple. tout au long du flux logique.
Détection de caractéristiques
Nous devons d'abord vérifier si le navigateur actuel prend en charge les messages push. Nous pouvons vérifier si la méthode push est compatible avec deux vérifications simples.
- Recherchez serviceWorker sur navigator.
- Recherchez PushManager dans window.
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;
}
Les navigateurs sont de plus en plus pris en charge, tant pour les service workers que pour les messages push, il est toujours judicieux de détecter les caractéristiques à la fois progressivement.
Enregistrer un service worker
Grâce à la détection de la fonctionnalité, nous savons que les service workers et le mode Push sont pris en charge. Étape suivante est d'« enregistrer » notre service worker.
Lorsque nous enregistrons un service worker, nous indiquons au navigateur l'emplacement de notre fichier. Il s'agit toujours d'un fichier JavaScript, mais le navigateur lui accorde l'accès au service worker telles que les API push. Pour être plus précis, le navigateur exécute le fichier dans un service worker. environnement.
Pour enregistrer un service worker, appelez navigator.serviceWorker.register()
en transmettant le chemin d'accès à
notre fichier. Comme ceci:
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 que nous disposons d'un fichier service worker et indique son emplacement. Dans
le fichier de service worker se trouve à l'emplacement /service-worker.js
. Dans les coulisses du navigateur
procède comme suit après avoir appelé register()
:
Téléchargez le fichier service worker.
Exécutez le code JavaScript.
Si tout s'exécute correctement et qu'il n'y a pas d'erreur, la promesse renvoyée par
register()
est résolu. En cas d'erreur, quelle qu'elle soit, la promesse sera rejetée.
Si
register()
refuse, 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, une exception ServiceWorkerRegistration
est renvoyée. Nous l'utiliserons
pour accéder à l'API PushManager.
Compatibilité du navigateur avec l'API PushManager
Navigateurs pris en charge
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
Demande d'autorisation...
Notre service worker a été enregistré et nous sommes prêts à abonner l'utilisateur. L'étape suivante consiste à récupérer l'autorisation de l'utilisateur de lui envoyer des messages push.
L'API permettant d'obtenir des autorisations est relativement simple. L'API est récemment passée d'un rappel à renvoyer une promesse. La est que nous ne pouvons pas déterminer la version de l'API implémentée par la version actuelle navigateur. Vous devez donc implémenter les deux et les gérer.
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 ci-dessus, l'extrait de code important est l'appel
Notification.requestPermission()
Cette méthode affiche une invite pour l'utilisateur:
Une fois que l'utilisateur a interagi avec l'invite d'autorisation en appuyant
sur "Autoriser", "Bloquer" ou en la fermant,
Le résultat s'affiche sous forme de chaîne: 'granted'
, 'default'
ou 'denied'
.
Dans l'exemple de code ci-dessus, la promesse renvoyée par askPermission()
résout si l'autorisation
est accordé. Sinon, nous générons une erreur qui entraîne le rejet de la promesse.
Vous devez gérer un cas particulier si l'utilisateur clique sur le bouton . Si cette cela se produit, votre application Web ne pourra plus demander l'autorisation à l'utilisateur. Ils devront "débloquer" manuellement votre application en modifiant son état d'autorisation, qui est caché dans un panneau de paramètres. Réfléchissez bien à la façon et au moment où vous demandez l'autorisation à l'utilisateur, car s'ils cliquent sur "Bloquer", il n'est pas facile d'annuler cette décision.
La bonne nouvelle est que la plupart des utilisateurs sont heureux de donner leur autorisation tant que il sait pourquoi l'autorisation est demandée.
Nous verrons plus tard comment certains sites populaires demandent l'autorisation.
Abonner un utilisateur avec PushManager
Une fois notre service worker enregistré et l'autorisation obtenue, nous pouvons abonner un utilisateur en
Appel de registration.pushManager.subscribe()
en cours.
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;
});
}
Lors de l'appel de la méthode subscribe()
, nous transmettons un objet options, qui se compose à la fois
les paramètres obligatoires et facultatifs.
Examinons toutes les options que nous pouvons transmettre.
Options userVisibleOnly
Lorsque la technologie push a été ajoutée pour la première fois aux navigateurs, il n'était pas certain que les développeurs en mesure d'envoyer un message push et de ne pas afficher de notification. Ceci est communément appelé silencieux car l'utilisateur ne savait pas qu'un événement s'était passé en arrière-plan.
Le problème était que les développeurs puissent faire des choses désagréables, comme suivre la position d'un utilisateur sur un sans que l'utilisateur s'en aperçoive.
Pour éviter ce scénario et laisser aux auteurs de spécifications le temps de réfléchir à la meilleure façon d'y parvenir
, l'option userVisibleOnly
a été ajoutée et la transmission de la valeur true
est symbolique
vous vous êtes mis d'accord avec le navigateur : l'application Web affiche une notification à chaque fois
(pas de transmission silencieuse).
Pour le moment, vous devez transmettre la valeur true
. Si vous n'incluez pas le paramètre
userVisibleOnly
ou transmettez false
, vous obtenez l'erreur suivante:
Pour le moment, Chrome n'est compatible qu'avec l'API Push pour les abonnements qui entraînent
messages visibles par les utilisateurs. Vous pouvez l'indiquer en appelant
pushManager.subscribe({userVisibleOnly: true})
à la place. Voir
https://goo.gl/yqv4Q4 pour en savoir plus.
On dirait que la notification push silencieuse globale ne sera jamais implémentée dans Chrome. À la place, les auteurs de spécifications explorent le concept d'API budgétaire qui permettra aux applications Web d'atteindre nombre de messages push silencieux en fonction de l'utilisation d'une application Web.
Option applicationServerKey
Nous avons brièvement mentionné les "clés de serveur d'applications". dans la section précédente. "Application "Clés de serveur" sont utilisés par un service push pour identifier l'application qui abonne un utilisateur pour s'assurer que la même application envoie des messages à cet utilisateur.
Les clés de serveur d'applications sont une paire de clés publique et privée propre à votre application. La clé privée doit rester secrète pour votre application et la clé publique peut être partagée en toute liberté.
L'option applicationServerKey
transmise dans l'appel subscribe()
est l'option publique de l'application
. Le navigateur transmet cette information à un service push lors de l'abonnement de l'utilisateur.
peut lier la clé publique de votre application au PushSubscription
de l'utilisateur.
Le schéma ci-dessous illustre ces étapes.
- Votre application Web est chargée dans un navigateur et vous appelez
subscribe()
en transmettant votre la clé du serveur d'applications. - Le navigateur envoie ensuite une requête réseau à un service push qui va générer un point de terminaison, associer ce point de terminaison à la clé publique de l'application et renvoyer le point de terminaison au navigateur.
- Le navigateur ajoutera ce point de terminaison à
PushSubscription
, qui est renvoyé via lasubscribe()
.
Par la suite, si vous souhaitez envoyer un message push, vous devez créer un en-tête Authorization qui contiendra les informations signées avec la clé privée de votre serveur d'applications. Lorsque reçoit une demande d'envoi d'un message push, il peut valider cet en-tête Authorization signé en recherchant la clé publique liée au point de terminaison qui reçoit la requête. Si la signature est si valide, le service push sait qu'il doit provenir du serveur d'applications avec le paramètre clé privée correspondante. C'est essentiellement une mesure de sécurité qui empêche toute autre personne d'envoyer aux utilisateurs d'une application.
Techniquement, applicationServerKey
est facultatif. Cependant, l'approche la plus simple
dans Chrome l'exige, tandis que d'autres navigateurs peuvent l'exiger dans
à l'avenir. Il est facultatif sur Firefox.
La spécification qui définit quelle doit être la clé du serveur d'applications est la spécification VAPID. Chaque fois que vous lisez des informations faisant référence à des clés de serveur d'applications ou VAPID, souvenez-vous simplement 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'applications en accédant à web-push-codelab.glitch.me, ou vous pouvez utiliser le Ligne de commande web-push pour générer des clés en procédant comme suit:
$ npm install -g web-push
$ web-push generate-vapid-keys
Vous n'avez besoin de créer ces clés qu'une seule fois pour votre application. Veillez simplement à conserver clé privée privée. (Oui, je viens de le dire.)
Autorisations et abonnement()
Appeler subscribe()
a un effet secondaire. Si votre application Web ne dispose pas d'autorisations pour
des notifications au moment de l'appel de subscribe()
, le navigateur demandera
des autorisations pour vous. C'est utile si votre interface utilisateur
fonctionne avec ce flux, mais si vous voulez plus
(et je pense que la plupart des développeurs le feront), s'en tenir à l'API Notification.requestPermission()
.
que nous avons utilisés précédemment.
Qu'est-ce qu'un abonnement PushSubscription ?
Nous appelons subscribe()
et transmettons certaines options. En retour, nous obtenons une promesse qui renvoie
PushSubscription
, ce qui génère un code semblable à celui-ci:
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 à l'envoi d'un message push.
des messages à cet utilisateur. Si vous imprimez le contenu à l'aide de JSON.stringify()
, vous verrez
suivantes:
{
"endpoint": "https://some.pushservice.com/something-unique",
"keys": {
"p256dh":
"BIPUL12DLfytvTajnryr2PRdAgXS3HGKiLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WAkAPIxr4gK0_dQds4yiI=",
"auth":"FPssNDTKnInHVndSTdbKFw=="
}
}
endpoint
correspond à l'URL des services push. Pour déclencher un message push, effectuez 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.
(nous y reviendrons plus tard dans cette section).
Réabonnement régulier pour éviter l'expiration
Lorsque vous vous abonnez aux notifications push, vous recevez souvent une PushSubscription.expirationTime
de null
. En théorie, cela signifie que l'abonnement n'expire jamais (contrairement à DOMHighResTimeStamp
, qui vous indique le moment exact où l'abonnement expire). Dans la pratique, il est toutefois courant que les navigateurs laissent toujours les abonnements expirer, par exemple si aucune notification push n'a été reçue depuis plus longtemps ou si le navigateur détecte que l'utilisateur n'utilise pas une application disposant de l'autorisation de notification push. Pour éviter cela, l'un des moyens consiste à réabonner l'utilisateur à chaque notification reçue, comme illustré dans l'extrait de code suivant. Vous devez donc envoyer des notifications suffisamment fréquemment pour que le navigateur n'expire pas automatiquement. Vous devez donc évaluer très attentivement les avantages et les inconvénients des notifications légitimes par rapport à l'envoi de spam involontaire à l'utilisateur afin que l'abonnement n'expire pas. En fin de compte, vous ne devez pas essayer de vous battre contre le 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);
});
}
Envoyer un abonnement à votre serveur
Une fois que vous disposez d'un abonnement push, vous pouvez l'envoyer à votre serveur. C'est à vous
de décider comment vous
mais une petite astuce consiste à utiliser JSON.stringify()
pour extraire toutes les données nécessaires
abonnement. Vous pouvez également assembler les mêmes
manuellement, comme ceci:
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);
L'envoi de l'abonnement s'effectue sur la page Web comme 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 de nœud reçoit cette demande 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.',
},
}),
);
});
});
Avec les détails PushSubscription
sur notre serveur, nous pouvons envoyer à l'utilisateur
un message à tout moment.
Réabonnement régulier pour éviter l'expiration
Lorsque vous vous abonnez aux notifications push, vous recevez souvent une PushSubscription.expirationTime
de null
. En théorie, cela signifie que l'abonnement n'expire jamais (contrairement à DOMHighResTimeStamp
, qui vous indique le moment exact où l'abonnement expire). En pratique, il est toutefois courant que les navigateurs laissent toujours les abonnements expirer, par exemple si aucune notification push n'a été reçue pendant une longue période ou si le navigateur détecte que l'utilisateur n'utilise pas l'application disposant de l'autorisation de notification push. Pour éviter cela, l'un des moyens consiste à réabonner l'utilisateur à chaque notification reçue, comme illustré dans l'extrait de code suivant. Vous devez donc envoyer des notifications suffisamment fréquemment pour que le navigateur n'expire pas automatiquement. Vous devez donc évaluer très attentivement les avantages et les inconvénients d'un besoin de notification légitime par rapport à l'envoi de spam à l'utilisateur afin que l'abonnement n'expire pas. En fin de compte, vous ne devez pas essayer de vous battre contre le 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 posées à ce stade:
Puis-je changer le service push utilisé par un navigateur ?
Non. Le service push est sélectionné par le navigateur. Comme nous l'avons vu
subscribe()
, le navigateur enverra des requêtes réseau au service push
pour récupérer les détails de l'abonnement PushSubscription.
Chaque navigateur utilise un service push différent, n'a-t-il pas des API différentes ?
Tous les services push attendront la même API.
Cette API courante s'appelle Protocole Web Push et décrit la requête réseau que votre application devra exécuter pour déclencher un message push.
Si j'abonne un utilisateur sur son ordinateur, le sera-t-il également sur son téléphone ?
Malheureusement non. L'utilisateur doit activer la fonctionnalité Push sur chaque navigateur qu'il souhaite utiliser. recevoir les messages. Notez également que cela nécessitera l'utilisateur accordant l'autorisation sur chaque appareil.
Étapes suivantes
- Présentation des notifications push Web
- Fonctionnement du mode Push
- Abonnement d'un utilisateur
- Expérience utilisateur des autorisations
- Envoyer des messages à l'aide des bibliothèques Web Push
- Protocole Web Push
- Gérer les événements push
- Afficher une notification
- Comportement des notifications
- Formats de notification courants
- Questions fréquentes sur les notifications push
- Problèmes courants et signalement de bugs