Najpierw musisz uzyskać od użytkownika zgodę na wysyłanie mu wiadomości push,
wypróbuj PushSubscription
.
Użycie interfejsu JavaScript API jest stosunkowo proste, więc nieprzekraczający ich logiki.
Wykrywanie cech
Najpierw musimy sprawdzić, czy bieżąca przeglądarka faktycznie obsługuje wiadomości push. Możemy sprawdzić, czy wypychanie jest obsługiwane na podstawie 2 prostych kontroli.
- Sprawdź zasób serviceWorker w narzędziu navigator.
- Sprawdź PushManager w oknie 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;
}
Liczba obsługiwanych przeglądarek jest coraz wyższa zarówno w przypadku mechanizmów Service Worker, w wiadomościach push, zawsze dobrze jest włączyć wykrywanie stopniowego ulepszania.
Rejestrowanie skryptu service worker
Dzięki funkcji wykrywania wiemy, że obsługiwane są zarówno mechanizmy Service Worker, jak i Push. Następny krok jest „rejestracja” nasz skrypt service worker.
Gdy rejestrujemy skrypt service worker, przeglądarka informuje przeglądarkę, gdzie znajduje się ten plik. Plik nadal to JavaScript, ale przeglądarka „udzieli do niego dostępu” do skryptu service worker Interfejsy API, w tym push. Dokładniej rzecz ujmując, przeglądarka uruchamia plik w skrypcie service worker dla środowiska.
Aby zarejestrować skrypt service worker, wywołaj navigator.serviceWorker.register()
, przekazując ścieżkę do
do pliku. W ten sposób:
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);
});
}
Ta funkcja informuje przeglądarkę, że mamy plik service worker i gdzie się znajduje. W
w tym przypadku plik service worker znajduje się pod adresem /service-worker.js
. Za kulisami przeglądarki
po wywołaniu numeru register()
wykona te czynności:
Pobierz plik service worker.
Uruchom kod JavaScript.
Jeśli wszystko działa prawidłowo i nie ma błędów, obietnica zwrócona przez funkcję
register()
zostanie rozwiązany. Jeśli wystąpią jakiekolwiek błędy, obietnica zostanie odrzucona.
Jeśli
register()
odrzuci żądanie, dokładnie sprawdź kod JavaScript pod kątem literówek lub błędów w Narzędziach deweloperskich w Chrome.
Po rozwiązaniu problemu register()
zwraca wartość ServiceWorkerRegistration
. Wykorzystamy to
aby uzyskać dostęp do interfejsu PushManager API.
Zgodność przeglądarki z interfejsem PushManager API
Proszę o zgodę
Zarejestrowaliśmy nasz skrypt service worker i jest on gotowy do subskrypcji użytkownika. Następnym krokiem jest zgody użytkownika na wysyłanie mu wiadomości push.
Interfejs API do uzyskiwania uprawnień jest stosunkowo prosty. Wadą jest jednak to, interfejs API niedawno zmienił wywołanie zwrotne na zwrot obietnicy. Problem w tym, że nie możemy określić, która wersja interfejsu API jest zaimplementowana przeglądarki, więc musisz wdrożyć je wszystkie i je obsługiwać.
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.");
}
});
}
W powyższym kodzie ważnym fragmentem kodu jest wywołanie funkcji
Notification.requestPermission()
Ta metoda spowoduje wyświetlenie użytkownikowi tych informacji:
Gdy użytkownik wejdzie w interakcję z prośbą o uprawnienia, naciskając Zezwól, Blokuj lub zamykając
wynik zostanie podany w postaci ciągu: 'granted'
, 'default'
lub 'denied'
.
W przykładowym kodzie powyżej obietnica zwrócona przez funkcję askPermission()
jest rozpatrywana, jeśli uprawnienie
zostanie zaakceptowana. W przeciwnym razie
popełnimy błąd i odrzucimy obietnicę.
Jedną z skrajnych sytuacji jest kliknięcie przycisku „Zablokuj” Przycisk Jeśli aplikacja nie będzie mogła ponownie poprosić użytkownika o zgodę. Będą musieli ręcznie „odblokuj” przez zmianę stanu uprawnień aplikacji, która jest w kodzie w panelu ustawień. Dobrze zastanów się, w jaki sposób i kiedy prosisz użytkownika o zgodę, bo jeśli klikną przycisk blokowania, nie będzie można łatwo cofnąć tej decyzji.
Dobra wiadomość jest taka, że większość użytkowników chętnie udziela zgody wie, dlaczego prosi o pozwolenie.
Później omówimy, w jaki sposób niektóre popularne witryny proszą o zgodę.
Subskrybowanie użytkownika za pomocą PushManager
Gdy już zarejestrujemy mechanizm Service Worker i otrzymamy zgodę użytkownika,
Dzwonię pod 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;
});
}
Wywołując metodę subscribe()
, przekazujemy obiekt options, który składa się z obu
wymagane i opcjonalne parametry.
Przyjrzyjmy się wszystkim opcjom, które można przekazać.
Opcje userVisibleOnly
Kiedy po raz pierwszy dodano tryb push do przeglądarek, nie było pewności, czy programiści powinni wysyłać wiadomości push bez wyświetlania powiadomień. Jest to tzw. tryb cichy ponieważ użytkownik nie wiedział, że coś wydarzyło się w tle.
Deweloperzy mogli się obawiać, że programiści mogli wykonywać szkodliwe działania, np. śledzić lokalizację użytkownika na bez wiedzy użytkownika.
Aby uniknąć takiej sytuacji i dać autorom specyfikacji czas na zastanowienie się, jak najlepiej temu zaradzić
funkcja userVisibleOnly
została dodana i przekazanie wartości true
jest symbolem
zgadza się z przeglądarką, że aplikacja internetowa będzie pokazywać powiadomienie przy każdym żądaniu push
odebranie (tj. brak cichych powiadomień push).
W tej chwili musisz przekazać wartość true
. Jeśli nie podasz parametru
userVisibleOnly
klucz lub przekaz w false
spowoduje błąd:
Chrome obsługuje obecnie interfejs Push API tylko w przypadku subskrypcji, które powodują
Możesz to poinformować, dzwoniąc
pushManager.subscribe({userVisibleOnly: true})
. Zobacz
Więcej informacji znajdziesz na stronie https://goo.gl/yqv4Q4.
Obecnie wygląda na to, że dyskretne przekazywanie push nigdy nie zostanie wdrożone w Chrome. Zamiast tego: autorzy specyfikacji pracują nad koncepcją budżetowego interfejsu API, który pozwoli aplikacjom internetowym liczba cichych wiadomości push na podstawie użycia aplikacji internetowej.
Opcja applicationServerKey
Wspomnieliśmy krótko o „kluczach serwera aplikacji”. w poprzedniej sekcji. „Aplikacja klucze serwera” są używane przez usługę push do identyfikowania aplikacji subskrybującej użytkownika oraz upewnić się, że ta sama aplikacja wysyła wiadomości do tego użytkownika.
Klucze serwera aplikacji to para kluczy publicznych i prywatnych, które są unikalne dla Twojej aplikacji. Klucz prywatny powinien być tajny dla aplikacji, a klucz publiczny może być dostępny dla wszystkich. swobodnie.
Opcja applicationServerKey
przekazywana do wywołania subscribe()
jest publiczną aplikacją
. Przeglądarka przekazuje go do usługi push podczas subskrybowania użytkownika, co oznacza
usługa może powiązać klucz publiczny aplikacji z PushSubscription
użytkownika.
Schemat poniżej ilustruje te kroki.
- Twoja aplikacja internetowa jest wczytywana w przeglądarce i wywołuje funkcję
subscribe()
, przekazując ją publicznie klucza serwera aplikacji. - Następnie przeglądarka wysyła żądanie sieciowe do usługi push, która generuje punkt końcowy. powiąż ten punkt końcowy z kluczem publicznym aplikacji i zwróć punkt końcowy do przeglądarki.
- Przeglądarka doda ten punkt końcowy do
PushSubscription
, który jest zwracany przez metodęsubscribe()
.
Jeśli później zechcesz wysłać wiadomość push, musisz utworzyć nagłówek Authorization który będzie zawierał informacje podpisane kluczem prywatnym serwera aplikacji. Gdy usługa push otrzymuje żądanie wysłania wiadomości push, może zweryfikować ten podpisany nagłówek Authorization wyszukując klucz publiczny połączony z punktem końcowym odbierającym żądanie. Jeśli podpis to prawidłowy, dla usługi push wie, że musi pochodzić z serwera aplikacji z kluczem prywatnym. To w zasadzie takie zabezpieczenie, które uniemożliwia innym wysyłane do użytkowników aplikacji.
Z technicznego punktu widzenia atrybut applicationServerKey
jest opcjonalny. Najłatwiej jednak
wymaga go wdrożenie w Chrome, a inne przeglądarki mogą go wymagać
przyszłości. W przeglądarce Firefox jest opcjonalny.
Specyfikacja określająca, jaki powinien być klucz serwera aplikacji specyfikację VAPID. Za każdym razem, gdy przeczytasz tekst odnoszący się do „kluczy serwera aplikacji” lub „Klucze VAPID” – pamiętaj, że to jest to samo.
Jak tworzyć klucze serwera aplikacji
Publiczny i prywatny zestaw kluczy serwera aplikacji możesz utworzyć, odwiedzając web-push-codelab.glitch.me lub możesz użyć wiersz poleceń web-push aby wygenerować klucze, wykonaj te czynności:
$ npm install -g web-push
$ web-push generate-vapid-keys
Klucze wystarczy utworzyć dla danej aplikacji tylko raz. Pamiętaj tylko, aby prywatny klucz prywatny. (Tak, właśnie to powiedziałem).
Uprawnienia i subscription()
Wywołanie funkcji subscribe()
ma jeden efekt uboczny. Jeśli Twoja aplikacja internetowa nie ma uprawnień do
wyświetlania powiadomień w momencie wywołania funkcji subscribe()
, przeglądarka poprosi o żądanie
i uprawnienia dostępu. Jest to przydatne, jeśli Twój interfejs działa z tym procesem, ale jeśli chcesz mieć więcej możliwości
(jak myślę, większość deweloperów) trzymaj się interfejsu API Notification.requestPermission()
.
którą użyliśmy wcześniej.
Co to jest PushSubscription?
Nazywamy subscribe()
i przekazujemy kilka opcji, a w zamian dostajemy obietnicę obejmującą
PushSubscription
w wyniku czego powstaje kod podobny do tego:
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;
});
}
Obiekt PushSubscription
zawiera wszystkie wymagane informacje potrzebne do wysłania żądania push.
wiadomości do tego użytkownika. Jeśli wydrukujesz treści za pomocą JSON.stringify()
, pojawi się przycisk
:
{
"endpoint": "https://some.pushservice.com/something-unique",
"keys": {
"p256dh":
"BIPUL12DLfytvTajnryr2PRdAgXS3HGKiLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WAkAPIxr4gK0_dQds4yiI=",
"auth":"FPssNDTKnInHVndSTdbKFw=="
}
}
endpoint
to adres URL usług push. Aby aktywować wiadomość push, wyślij żądanie POST
do tego adresu URL.
Obiekt keys
zawiera wartości używane do szyfrowania danych wiadomości wysyłanych za pomocą wiadomości push
(którą omówimy później w tej sekcji).
Regularna ponowna subskrypcja w celu uniknięcia jej wygaśnięcia
Gdy subskrybujesz powiadomienia push, często otrzymujesz PushSubscription.expirationTime
w wysokości null
. Teoretycznie oznacza to, że subskrypcja nigdy nie wygasa (w przeciwieństwie do tego, że otrzymujesz DOMHighResTimeStamp
, który wskazuje dokładny moment wygaśnięcia subskrypcji). W praktyce często jednak wygasają subskrypcje, na przykład gdy przez dłuższy czas nie otrzymujesz powiadomień push lub gdy przeglądarka wykryje, że użytkownik nie używa aplikacji, która ma uprawnienia do powiadomień push. Jednym z wzorców zapobiegających takiej sytuacji jest ponowne subskrybowanie użytkownika po każdym otrzymaniu powiadomienia, tak jak pokazano w tym fragmencie. Wymaga to wysyłania powiadomień na tyle często, aby przeglądarka nie wygasła automatycznie. Warto bardzo dokładnie rozważyć zalety i wady uzasadnionych potrzeb w zakresie powiadomień, aby uniknąć przypadkowego spamowania użytkownika, tak aby subskrypcja nie wygasła. Podsumowując, nie próbuj walczyć z przeglądarką, aby chronić użytkownika przed zapomnianymi subskrypcjami powiadomień.
/* 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);
});
}
Wyślij subskrypcję na swój serwer
Gdy masz już subskrypcję push, chcesz ją wysłać na swój serwer. To zależy od Ciebie
to jednak tylko JSON.stringify()
, by pobrać wszystkie niezbędne dane z
obiektu subskrypcji. Możesz też połączyć w całości to samo
wynik ręcznie, w ten sposób:
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);
Subskrypcję możesz wysłać na stronie internetowej w ten sposób:
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.');
}
});
}
Serwer węzła odbiera to żądanie i zapisuje dane w bazie danych na potrzeby późniejszego użycia.
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.',
},
}),
);
});
});
Mając dane PushSubscription
na naszym serwerze, możemy wysłać do użytkownika
wiadomość, kiedy tylko zechcemy.
Regularna ponowna subskrypcja w celu uniknięcia jej wygaśnięcia
Gdy subskrybujesz powiadomienia push, często otrzymujesz PushSubscription.expirationTime
w wysokości null
. Teoretycznie oznacza to, że subskrypcja nigdy nie wygasa (w przeciwieństwie do tego, że otrzymujesz DOMHighResTimeStamp
, który wskazuje dokładny moment wygaśnięcia subskrypcji). W praktyce często jednak wygasają subskrypcje, na przykład gdy przez dłuższy czas nie odebrano powiadomień push lub gdy przeglądarka wykryje, że użytkownik nie korzysta z aplikacji z uprawnieniami do powiadomień push. Jednym z wzorców zapobiegających takiej sytuacji jest ponowne subskrybowanie użytkownika po każdym otrzymaniu powiadomienia, tak jak pokazano w tym fragmencie. Wymaga to wysyłania powiadomień na tyle często, by przeglądarka nie wygasła automatycznie. Warto bardzo dokładnie rozważyć zalety i wady uzasadnionych powiadomień, a tym samym spamowanie użytkownika, aby subskrypcja nie wygasła. Podsumowując, nie próbuj walczyć z przeglądarką, aby chronić użytkownika przed zapomnianymi subskrypcjami powiadomień.
/* 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);
});
}
Najczęstsze pytania
Oto kilka często zadawanych pytań:
Czy mogę zmienić usługę push używaną w przeglądarce?
Nie. Usługa push jest wybierana przez przeglądarkę i zgodnie z
subscribe()
, przeglądarka będzie wysyłać żądania sieciowe do usługi push
aby pobrać szczegóły składające się na PushSubscription.
Każda przeglądarka korzysta z innej usługi Push. Czy nie mają one różnych interfejsów API?
Wszystkie usługi push będą oczekiwać tego samego interfejsu API.
Ten typowy interfejs API nosi nazwę Protokół Web Push Protocol i opisuje żądanie sieciowe, musi być utworzona aplikacja, aby aktywować komunikat push.
Czy jeśli subskrybuję użytkownika na komputerze, czy on też ma subskrypcję na telefonie?
Nie. Użytkownik musi zarejestrować się w usłudze push w każdej przeglądarce, dla odbierania wiadomości. Warto też zauważyć, że będzie to wymagać o których użytkownik przyznaje odpowiednie uprawnienia na każdym z urządzeń.
Co dalej
- Omówienie powiadomień push w internecie
- Jak działa push
- Subskrybowanie użytkownika
- UX uprawnień
- Wysyłanie wiadomości za pomocą bibliotek Web Push
- Protokół Web Push Protocol
- Obsługa zdarzeń push
- Wyświetlanie powiadomienia
- Działanie powiadomień
- Typowe wzorce powiadomień
- Najczęstsze pytania na temat powiadomień push
- Typowe problemy i zgłaszanie błędów