В этом практическом занятии вы шаг за шагом узнаете, как создать клиент push-уведомлений. К концу практического занятия у вас будет клиент, который:
- Подписывает пользователя на push-уведомления.
- Получает push-сообщения и отображает их в виде уведомлений.
- Отписывает пользователя от push-уведомлений.
Эта практическая работа направлена на обучение на практике и не слишком подробно рассматривает концепции. Подробнее о концепциях push-уведомлений читайте в статье «Как работают push-уведомления?» .
Серверный код этой лабораторной работы уже готов. В ней вам останется только реализовать клиентскую часть. Чтобы узнать, как реализовать сервер push-уведомлений, ознакомьтесь с практической работой: Создание сервера push-уведомлений .
Совместимость с браузерами
Известно, что эта лабораторная работа работает со следующими комбинациями операционных систем и браузеров:
- Windows: Chrome, Edge
- macOS: Chrome, Firefox
- Android: Chrome, Firefox
Известно, что эта лабораторная работа не работает со следующими операционными системами (или комбинациями операционной системы и браузера):
- macOS: Brave, Edge, Safari
- iOS
Настраивать
Получите редактируемую копию кода
- Нажмите «Ремикс для редактирования», чтобы сделать проект редактируемым.
Настроить аутентификацию
Прежде чем запускать push-уведомления, необходимо настроить сервер и клиент с ключами аутентификации. Подробнее об этом см. в статье «Подпись запросов протокола web push» . Обычно секретные данные хранятся в файле .env
, похожем на этот.
VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
- Откройте
public/index.js
. - Замените
VAPID_PUBLIC_KEY_VALUE_HERE
на значение вашего открытого ключа.
Регистрация работника сферы услуг
В конечном итоге вашему клиенту понадобится сервис-воркер для получения и отображения уведомлений. Рекомендуется зарегистрировать сервис-воркер как можно раньше. Подробнее см. в разделе Получение и отображение push-сообщений в виде уведомлений .
- Замените комментарий
// TODO add startup logic here
следующим кодом:
// TODO add startup logic here
if ('serviceWorker' in navigator && 'PushManager' in window) {
navigator.serviceWorker.register('./service-worker.js').then(serviceWorkerRegistration => {
console.info('Service worker was registered.');
console.info({serviceWorkerRegistration});
}).catch(error => {
console.error('An error occurred while registering the service worker.');
console.error(error);
});
subscribeButton.disabled = false;
} else {
console.error('Browser does not support service workers or push messages.');
}
subscribeButton.addEventListener('click', subscribeButtonHandler);
unsubscribeButton.addEventListener('click', unsubscribeButtonHandler);
- Нажмите `Control+Shift+J` (или `Command+Option+J` на Mac), чтобы открыть DevTools.
- Перейдите на вкладку «Консоль» . Вы увидите сообщение
Service worker was registered.
Вход в консоль выполнен.
Запросить разрешение на push-уведомления
Никогда не запрашивайте разрешение на отправку push-уведомлений при загрузке страницы. Вместо этого ваш пользовательский интерфейс должен спрашивать у пользователя, хочет ли он получать push-уведомления. После того, как он явно подтвердит (например, нажав кнопку), вы можете начать формальный процесс получения разрешения на отправку push-уведомлений от браузера.
- В
public/index.js
замените комментарий// TODO
вsubscribeButtonHandler()
следующим кодом:
// TODO
// Prevent the user from clicking the subscribe button multiple times.
subscribeButton.disabled = true;
const result = await Notification.requestPermission();
if (result === 'denied') {
console.error('The user explicitly denied the permission request.');
return;
}
if (result === 'granted') {
console.info('The user accepted the permission request.');
}
- Вернитесь на вкладку приложения и нажмите «Подписаться на push- уведомления». Ваш браузер или операционная система, вероятно, спросят вас, хотите ли вы разрешить сайту отправлять вам push-уведомления. Нажмите «Разрешить» (или любую другую фразу, используемую в вашем браузере/ОС). В консоли вы увидите сообщение о том, был ли запрос принят или отклонён.
Подписаться на push-уведомления
Процесс подписки включает взаимодействие с веб-сервисом, управляемым поставщиком браузера, который называется push-сервисом . Получив информацию о подписке на push-уведомления, необходимо отправить её на сервер и обеспечить её долгосрочное хранение в базе данных. Подробнее о процессе подписки см. в статье «Подписка клиента на push-уведомления» .
- Добавьте следующий выделенный код в
subscribeButtonHandler()
:
subscribeButton.disabled = true;
const result = await Notification.requestPermission();
if (result === 'denied') {
console.error('The user explicitly denied the permission request.');
return;
}
if (result === 'granted') {
console.info('The user accepted the permission request.');
}
const registration = await navigator.serviceWorker.getRegistration();
const subscribed = await registration.pushManager.getSubscription();
if (subscribed) {
console.info('User is already subscribed.');
notifyMeButton.disabled = false;
unsubscribeButton.disabled = false;
return;
}
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlB64ToUint8Array(VAPID_PUBLIC_KEY)
});
notifyMeButton.disabled = false;
fetch('/add-subscription', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(subscription)
});
Параметр userVisibleOnly
должен иметь значение true
. Возможно, когда-нибудь появится возможность отправлять push-сообщения без отображения видимых пользователю уведомлений ( тихие push- уведомления), но в настоящее время браузеры не поддерживают такую возможность из-за проблем с конфиденциальностью.
Значение applicationServerKey
основано на служебной функции, которая преобразует строку base64 в массив Uint8Array. Это значение используется для аутентификации между вашим сервером и службой push-уведомлений.
Отписаться от push-уведомлений
После того как пользователь подписался на push-уведомления, ваш пользовательский интерфейс должен предоставить возможность отписаться на случай, если пользователь передумает и больше не захочет получать push-уведомления.
- Замените комментарий
// TODO
вunsubscribeButtonHandler()
следующим кодом:
// TODO
const registration = await navigator.serviceWorker.getRegistration();
const subscription = await registration.pushManager.getSubscription();
fetch('/remove-subscription', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({endpoint: subscription.endpoint})
});
const unsubscribed = await subscription.unsubscribe();
if (unsubscribed) {
console.info('Successfully unsubscribed from push notifications.');
unsubscribeButton.disabled = true;
subscribeButton.disabled = false;
notifyMeButton.disabled = true;
}
Получайте push-сообщение и отображайте его как уведомление
Как упоминалось ранее, вам нужен сервис-воркер для обработки получения и отображения сообщений, отправленных клиенту с вашего сервера. Подробнее см. в разделе Получение и отображение отправленных сообщений в виде уведомлений .
- Откройте
public/service-worker.js
и замените комментарий// TODO
в обработчике событийpush
сервис-воркера следующим кодом:
// TODO
let data = event.data.json();
const image = 'logo.png';
const options = {
body: data.options.body,
icon: image
}
self.registration.showNotification(
data.title,
options
);
- Вернитесь на вкладку приложения.
- Нажмите «Уведомить меня» . Вы получите push-уведомление.
- Попробуйте открыть URL-адрес вкладки вашего приложения в других браузерах (или даже на других устройствах), пройти процедуру оформления подписки и нажать «Уведомить всех» . Вы должны получить одинаковое push-уведомление во всех браузерах, на которые вы подписаны. См. раздел «Совместимость браузеров» , чтобы ознакомиться со списком совместимых и несовместимых сочетаний браузера и ОС.
Вы можете настроить уведомление различными способами. Подробнее см. в параметрах ServiceWorkerRegistration.showNotification()
.
Открывать URL-адрес, когда пользователь нажимает на уведомление
В реальной жизни вы, вероятно, будете использовать уведомление, чтобы повторно привлечь пользователя и побудить его посетить ваш сайт. Для этого вам потребуется более детально настроить сервис-воркер.
- Замените комментарий
// TODO
в обработчике событийnotificationclick
сервисного работника следующим кодом:
// TODO
event.notification.close();
event.waitUntil(self.clients.openWindow('https://web.dev'));
- Вернитесь на вкладку приложения, отправьте себе ещё одно уведомление и нажмите на него. Браузер должен открыть новую вкладку и загрузить
https://web.dev
.
Следующие шаги
- Взгляните на
ServiceWorkerRegistration.showNotification()
чтобы узнать обо всех возможных способах настройки уведомлений. - Прочитайте обзор push-уведомлений для более глубокого концептуального понимания того, как работают push-уведомления.
- Ознакомьтесь с практической работой: создание сервера push-уведомлений, чтобы узнать, как создать сервер, который управляет подписками и отправляет запросы по протоколу web push.
- Попробуйте Notification Generator , чтобы протестировать все способы настройки уведомлений.