Перейти к основному содержимому

2.04. Push-рассылка и уведомления

Всем

Push-рассылка и уведомления в веб-приложениях

Push-рассылка (Push Notifications) — возможность отправлять уведомления пользователям даже тогда, когда они не находятся на сайте. Работает через Service Worker и Push API, интегрированный с облачными сервисами (Firebase Cloud Messaging, Mozilla Push Service). Пользователь должен дать разрешение, что обеспечивает контроль над уведомлениями.

Push-уведомления — это короткие сообщения, которые веб-приложение может показать пользователю даже тогда, когда вкладка с сайтом закрыта, браузер свёрнут или работает в фоне.

Они напоминают системные уведомления операционной системы: появляются в углу экрана, могут вибрировать на телефоне, воспроизводить звук, отображать иконку и заголовок. При нажатии — открывают конкретную страницу приложения.

Такой уровень взаимодействия стал возможен благодаря трём технологиям, появившимся в 2015–2017 годах и принятым всеми основными браузерами:

  • Service Worker — фоновый скрипт вне контекста страницы;
  • Push API — интерфейс для получения внешних событий;
  • Notifications API — интерфейс для отображения уведомлений.

Эти три компонента работают вместе как команда: Push API получает сигнал извне, Service Worker обрабатывает его и решает, стоит ли показывать уведомление, а Notifications API превращает решение в визуальное сообщение.


Service Worker

Service Worker — это JavaScript-файл, который браузер загружает и исполняет в фоновом режиме. Он не привязан к конкретной вкладке и может жить дольше, чем сама страница.

Основные свойства Service Worker:

  • Запускается один раз на домен (или на область действия — scope);
  • Не имеет доступа к DOM и не может напрямую менять интерфейс;
  • Может перехватывать сетевые запросы, кэшировать ресурсы, планировать фоновые операции;
  • Имеет ограниченное время жизни: браузер «усыпляет» его при бездействии, но пробуждает по событиям (сетевой запрос, push-сообщение, таймер);
  • Требует HTTPS (даже на localhost — для безопасности).

Service Worker — это фоновый скрипт, который работает независимо от страницы. Он может перехватывать и кэшировать запросы, синхронизировать данные, показывать уведомления, запускаться по расписанию. Именно он решает:
— кэшировать ли изображения для быстрой загрузки при следующем заходе;
— отправить ли данные на сервер при появлении интернета, если ранее связь прервалась;
— показать ли уведомление, когда пришёл push.

Service Worker устанавливается явно: сайт регистрирует его с помощью navigator.serviceWorker.register(). После этого браузер запускает жизненный цикл: installactivateidle/waitingrunning по событию.

💡 Пример жизненного цикла:
Пользователь впервые зашёл на сайт → Service Worker загрузился и выполнил install → сохранил критические файлы в кэш → перешёл в состояние activated → начал слушать события.
На следующем визите — браузер сразу использует кэшированную версию, даже если интернет отсутствует. Это основа работы Progressive Web Apps.


Push API

Push API — это механизм, позволяющий внешнему серверу отправить сигнал в браузер пользователя через облачный push-сервис.

Важно понимать: веб-приложение не может напрямую отправить сообщение в браузер пользователя, если тот не находится на сайте. Соединение разорвано. Чтобы преодолеть эту преграду, используется посредник — push-сервер, управляемый браузерным вендором или доверенной третьей стороной.

Стандартная схема:

  1. Пользователь заходит на сайт и разрешает получать уведомления.
  2. Браузер генерирует уникальный push-токен — адрес, по которому можно доставить сообщение именно этому устройству и профилю.
  3. Push-токен отправляется на сервер приложения и сохраняется в базе данных в привязке к пользователю.
  4. Когда сервер хочет отправить уведомление — он обращается к облачному push-сервису (например, Firebase Cloud Messaging или Mozilla Push Service) и передаёт туда push-токен и payload (содержимое).
  5. Push-сервис находит браузер по токену и доставляет сигнал.
  6. Браузер пробуждает Service Worker и передаёт ему событие push.
  7. Service Worker создаёт и показывает уведомление через self.registration.showNotification().

Эта схема называется web push protocol. Она не зависит от конкретного фреймворка или языка: любой сервер (Node.js, Python, Java, PHP) может отправлять push-сообщения, если умеет подписываться на push-сервис.

🔐 Безопасность:
Push-токен не содержит персональных данных, но он уникален и должен храниться конфиденциально. Если токен украден — злоумышленник может отправлять пользователю фишинговые уведомления от имени доверенного сайта. Поэтому:
— токен передаётся только по HTTPS;
— сервер валидирует, кому именно он отправляет сообщение;
— уведомления не содержат критически важных данных (например, код подтверждения из SMS лучше не слать в push — это нарушение принципа least privilege).


Notifications API

Notifications API — это интерфейс, через который Service Worker или веб-страница могут показать системное уведомление.

Вызов прост:

self.registration.showNotification('Новое сообщение', {
body: 'Вам ответили в чате',
icon: '/icons/chat-48.png',
badge: '/icons/badge-12.png', // маленькая иконка в списке уведомлений (Android)
tag: 'chat-reply', // группировка: повторные уведомления с тем же tag заменят старое
data: { chatId: 42 }, // произвольные данные — Service Worker передаст их при клике
requireInteraction: true // уведомление не исчезнет автоматически
});

Уведомление появляется в системной области уведомлений ОС. Пользователь может:

  • кликнуть по нему — тогда сработает обработчик события notificationclick в Service Worker, и можно открыть нужную страницу;
  • отклонить — сообщение исчезнет;
  • настроить глобальные разрешения для сайта (разрешить/запретить/настроить тихий режим).

📱 Особенности на мобильных устройствах:
— На iOS push-уведомления работают, но Service Worker ограничен (не поддерживает фоновую синхронизацию, Push API требует Safari 16.4+, апрель 2023);
— На Android — полная поддержка, включая rich notifications (кнопки действий, изображения в уведомлении);
— Некоторые браузеры (например, Samsung Internet) используют свой push-сервис, но API остаётся единым.


От пользователя — к разрешению

Push-уведомления невозможны без явного согласия. Браузер не позволяет сайту отправлять их просто так — это нарушало бы приватность и могло превратиться в спам.

Типичный сценарий запроса разрешения:

  1. Пользователь проводит время на сайте, взаимодействует с контентом — это сигнал доверия.
  2. В подходящий момент (не при заходе!) сайт показывает собственную кнопку: «Получать уведомления о новых статьях?».
  3. При клике вызывается Notification.requestPermission().
  4. Браузер выводит системный диалог: «site.ru хочет отправлять вам уведомления» с кнопками «Разрешить» / «Заблокировать».
  5. Если пользователь разрешил — сайт регистрирует Service Worker и подписывается на push-сервис.

🚫 Плохая практика:
— Запрашивать разрешение сразу при загрузке страницы;
— Скрывать кнопку «Отклонить» или делать её малозаметной;
— Использовать push для рекламы без ценности (скидки, акции без подписки на них).
Это ведёт к массовому отключению уведомлений и потере доверия.

Хорошая практика:
— Объяснить, зачем нужны уведомления и какую пользу они принесут;
— Разрешить легко отписаться (например, ссылка «Настроить уведомления» в каждом сообщении);
— Отправлять только релевантные события (статус заказа, ответ в обсуждении, начало трансляции — не «Мы вас помним!» раз в неделю).