Push уведомления

Push-уведомления предоставляют возможность отправлять пользователю информацию даже тогда, когда веб-приложение не активно в браузере. Во Vue.js их интеграция осуществляется через сочетание стандартного Web Push API и сервис-воркеров.


Регистрация сервис-воркера

Для работы push-уведомлений необходим сервис-воркер. В корневой папке проекта создаётся файл service-worker.js. Простейший пример:

self.addEventListener('push', event => {
  const data = event.data.json();
  event.waitUntil(
    self.registration.showNotification(data.title, {
      body: data.body,
      icon: data.icon,
      data: data.url
    })
  );
});

self.addEventListener('notificationclick', event => {
  event.notification.close();
  event.waitUntil(
    clients.openWindow(event.notification.data)
  );
});

Регистрация сервис-воркера во Vue выполняется обычно в main.js или App.vue:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js')
    .then(registration => {
      console.log('Service Worker зарегистрирован:', registration);
    })
    .catch(error => {
      console.error('Ошибка регистрации Service Worker:', error);
    });
}

Запрос разрешения на уведомления

Для получения разрешения используется стандартный метод Notification.requestPermission():

Notification.requestPermission().then(permission => {
  if (permission === 'granted') {
    console.log('Разрешение на уведомления предоставлено');
  } else {
    console.warn('Разрешение на уведомления отклонено');
  }
});

Важно учитывать, что браузеры требуют HTTPS для работы push-уведомлений и сервис-воркеров, за исключением локальной разработки (localhost).


Подписка на Push-сообщения

Для подписки используется объект PushManager, доступный через сервис-воркер:

navigator.serviceWorker.ready.then(registration => {
  const publicVapidKey = '<YOUR_PUBLIC_VAPID_KEY>';

  registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: urlBase64ToUint8Array(publicVapidKey)
  })
  .then(subscription => {
    console.log('Подписка на push:', subscription);
    // Отправка данных подписки на сервер
  })
  .catch(error => {
    console.error('Ошибка подписки:', error);
  });
});

function urlBase64ToUint8Array(base64String) {
  const padding = '='.repeat((4 - base64String.length % 4) % 4);
  const base64 = (base64String + padding)
    .replace(/\-/g, '+')
    .replace(/_/g, '/');

  const rawData = window.atob(base64);
  return Uint8Array.from([...rawData].map(char => char.charCodeAt(0)));
}

Ключевые моменты:

  • userVisibleOnly: true обязательно указывает, что уведомления всегда будут видимы пользователю.
  • applicationServerKey — публичный VAPID ключ, необходимый для аутентификации push-запросов на сервере.

Отправка push-уведомлений с сервера

На серверной стороне (Node.js) используется библиотека web-push:

const webPush = require('web-push');

const publicVapidKey = '<YOUR_PUBLIC_VAPID_KEY>';
const privateVapidKey = '<YOUR_PRIVATE_VAPID_KEY>';

webPush.setVapidDetails(
  'mailto:admin@example.com',
  publicVapidKey,
  privateVapidKey
);

const subscription = {/* объект подписки из клиента */};

const payload = JSON.stringify({
  title: 'Новое уведомление',
  body: 'Пример push-сообщения',
  icon: '/icon.png',
  url: 'https://example.com'
});

webPush.sendNotification(subscription, payload)
  .then(() => console.log('Уведомление отправлено'))
  .catch(err => console.error('Ошибка отправки уведомления:', err));

Особенности работы:

  • Push-сообщения передаются через сервисы браузеров, поэтому сервер не напрямую уведомляет клиента, а через push-сервис браузера.
  • Объект subscription должен храниться на сервере для последующих уведомлений.

Обработка событий уведомлений во Vue

В Vue можно использовать глобальные методы для обработки кликов по уведомлениям или состояния подписки:

export default {
  mounted() {
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.ready.then(registration => {
        registration.pushManager.getSubscription()
          .then(subscription => {
            if (subscription) {
              console.log('Пользователь уже подписан');
            } else {
              console.log('Подписка отсутствует');
            }
          });
      });
    }
  }
};

Для реактивного управления можно использовать Vuex или Composition API для хранения состояния подписки и отображения уведомлений в интерфейсе приложения.


Best Practices

  • Обновление сервис-воркера: при изменении логики push важно инкрементировать версию или использовать skipWaiting для обновления.
  • Фоновая синхронизация: можно совмещать push с Background Sync для обновления данных приложения до показа уведомления.
  • Минимизация нагрузки: отправлять уведомления только при действительно важной информации, чтобы не раздражать пользователя.
  • Тестирование: проверять работу уведомлений на разных браузерах, так как поддержка и ограничения могут различаться.

Push-уведомления во Vue.js сочетают возможности Web Push API и сервис-воркеров, позволяя создавать интерактивные приложения с высокой вовлечённостью пользователей. Правильная архитектура подписки, хранение ключей и управление событиями обеспечивают стабильную работу системы уведомлений.