W3docs

Исчерпывающее руководство по JavaScript Notifications API

Notifications API — веб-технология, позволяющая разработчикам отправлять уведомления и управлять ими прямо из веб-приложений.

Введение в Notifications API

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

На этой странице рассматривается полный жизненный цикл: проверка доступности API, запрос разрешения у пользователя, создание и настройка уведомлений, реакция на клики и отображение уведомлений из service worker, чтобы они продолжали работать после закрытия страницы. В конце изложены правила, не позволяющие уведомлениям стать навязчивыми.

Несколько фактов, которые стоит учесть перед написанием первой строки кода:

  • Уведомления требуют явного разрешения от пользователя. Показать их нельзя, пока разрешение не равно granted.
  • Они работают только в безопасном контексте (https:// или http://localhost при разработке).
  • Внешний вид и поведение уведомления определяются операционной системой, а не вашим CSS. Вы предоставляете содержимое; ОС решает, как его отображать.

Проверка поддержки

Всегда выполняйте определение возможностей перед использованием API, чтобы код корректно деградировал в средах, где он недоступен (старые браузеры, некоторые встроенные webview и серверный рендеринг):

if ('Notification' in window) {
  // The Notifications API is available
} else {
  console.log('This browser does not support notifications.');
}

Понимание разрешений

Состояние разрешения хранится в статическом свойстве Notification.permission и принимает одно из трёх строковых значений:

  • 'granted' — пользователь разрешил уведомления; можно их показывать.
  • 'denied' — пользователь заблокировал их; попытки показать уведомление молча игнорируются.
  • 'default' — пользователь ещё не принял решение; это значение обрабатывается как 'denied', пока вы не спросите.

Запросить разрешение можно с помощью Notification.requestPermission(). Метод возвращает промис, который разрешается в итоговую строку разрешения:

Notification.requestPermission().then((permission) => {
  console.log('Permission:', permission); // 'granted', 'denied', or 'default'
});
Внимание

Браузеры позволяют вызывать requestPermission() только в ответ на жест пользователя, например нажатие кнопки. Автоматический запрос разрешения при загрузке страницы широко блокируется и ухудшает пользовательский опыт — дожидайтесь момента, когда пользователь совершит действие, объясняющее, зачем нужны уведомления.

Надёжный паттерн сначала проверяет текущее состояние и запрашивает разрешение только тогда, когда решение ещё не принято ('default'):

async function ensurePermission() {
  if (Notification.permission === 'granted') {
    return true;
  }
  if (Notification.permission === 'denied') {
    return false; // can't re-prompt; the user must change it in browser settings
  }
  const permission = await Notification.requestPermission();
  return permission === 'granted';
}

Форма на основе промисов хорошо сочетается с async/await и общим Promise API.

Создание и отображение уведомлений

Когда разрешение равно granted, создайте уведомление с помощью конструктора Notification. Первый аргумент — заголовок (обязательный); второй — необязательный объект параметров.

if (Notification.permission === 'granted') {
  new Notification('Hello, world!', {
    body: 'Here is the body of the notification.',
    icon: '/icon-192.png'
  });
}

Уведомление появляется в момент создания объекта — отдельный метод «показать» вызывать не нужно.

Основные параметры

Объект параметров принимает множество полей. Наиболее полезные из них:

ПараметрТипНазначение
bodystringОсновной текст, отображаемый под заголовком.
iconURLИзображение рядом с уведомлением.
badgeURLНебольшая монохромная иконка для устройств с ограниченным пространством (преимущественно мобильных).
imageURLБолее крупное изображение в теле уведомления.
tagstringИдентификатор для группировки уведомлений; новое уведомление с тем же тегом заменяет старое.
dataanyПроизвольные данные, доступные в обработчике клика.
silentbooleanПри значении true отключает звук и вибрацию.
requireInteractionbooleanУдерживает уведомление на экране до явного закрытия пользователем (для десктопа).
lang / dirstringПодсказки о языке и направлении текста.
new Notification('New message', {
  body: 'You have 1 unread message from Alex.',
  icon: '/icon-192.png',
  tag: 'chat-alex',          // replacing an earlier "Alex" notification
  data: { conversationId: 42 },
  requireInteraction: true
});

Предотвращение спама уведомлений с помощью tag

Параметр tag — простейший способ избежать накопления дубликатов. Если от одного человека пришло три сообщения, повторное использование одного тега означает, что пользователь видит одно обновлённое уведомление вместо трёх:

function notifyUnread(count) {
  new Notification('Inbox', {
    body: `You have ${count} unread messages.`,
    tag: 'inbox-count' // each call updates the same notification
  });
}

События уведомлений

Экземпляр Notification генерирует события, которые можно отслеживать. Наиболее важное — click, возникающее, когда пользователь активирует уведомление:

const notification = new Notification('Interactive Notification', {
  body: 'Click me to do something',
  icon: '/icon-192.png'
});

notification.onclick = (event) => {
  event.preventDefault();    // stop the browser's default focus behavior
  window.open('https://example.com', '_blank');
  notification.close();      // remove the notification once handled
};

Другие доступные события: show (отображено), error (ошибка отображения) и close (закрыто). Обработчики можно также подключать через addEventListener — общий паттерн описан в разделе обработка событий в DOM.

Программное закрытие уведомлений

Вызовите close(), чтобы закрыть уведомление самостоятельно — удобно для удаления уведомления «загружается…» после завершения загрузки:

const note = new Notification('Downloading…', { tag: 'download' });

// later, when the work is done:
setTimeout(() => note.close(), 4000);

Беззвучные уведомления

Установите silent: true, чтобы показывать уведомление без звука и вибрации — подходит для низкоприоритетных фоновых обновлений:

new Notification('Silent Notification', {
  body: 'This is a silent notification.',
  silent: true
});

Уведомления из service worker

Стандартный конструктор Notification работает только пока страница открыта. Чтобы доставлять уведомления, когда сайт находится в фоне — или в ответ на серверное push-сообщение — показывайте их из service worker с помощью ServiceWorkerRegistration.showNotification():

// In the page: ask the service worker to show a notification
navigator.serviceWorker.ready.then((registration) => {
  registration.showNotification('Background-capable notification', {
    body: 'This can be shown even after the tab is closed.',
    icon: '/icon-192.png',
    actions: [
      { action: 'open', title: 'Open' },
      { action: 'dismiss', title: 'Dismiss' }
    ]
  });
});

Уведомления service worker также поддерживают кнопки действий (массив actions), которые простой конструктор не поддерживает. Обработка кликов выполняется внутри самого service worker:

// In the service worker (sw.js)
self.addEventListener('notificationclick', (event) => {
  event.notification.close();
  if (event.action === 'open') {
    event.waitUntil(clients.openWindow('/inbox'));
  }
});

Этот путь через service worker лежит в основе настоящего web push: сервер отправляет сообщение, Push API пробуждает service worker, и воркер вызывает showNotification().

Поддержка браузерами и особенности

  • Только безопасный контекст. Уведомления требуют HTTPS (или localhost). На страницах с http:// они работать не будут.
  • Разрешение сохраняется. Если пользователь выбрал 'denied', повторно запросить разрешение из JavaScript невозможно — необходимо изменить настройки в браузере. Не стоит повторять запросы.
  • iOS Safari исторически не поддерживал веб-уведомления; поддержка появилась только для сайтов, добавленных на главный экран как PWA. Всегда проверяйте наличие возможности.
  • Внешний вид определяется ОС. Не полагайтесь на конкретный размер, положение или оформление — сосредоточьтесь на чётком и лаконичном тексте.

Лучшие практики

Чтобы уведомления оставались полезной функцией, а не тем, что пользователи отключают:

  • Запрашивайте разрешение в контексте, после жеста. Просите его тогда, когда пользователь только что совершил действие, делающее уведомления очевидно полезными (например, включил оповещения), но никогда — при первой загрузке.
  • Уважайте отказ. Если разрешение равно 'denied', остановитесь. Повторные запросы технически невозможны, а навязчивость в интерфейсе подрывает доверие.
  • Будьте своевременны и актуальны. Отправляйте только те уведомления, которые пользователь действительно хотел бы получить в данный момент.
  • Используйте их экономно. Группируйте с помощью tag, объединяйте по возможности, и оставляйте уведомления для действительно важного — чрезмерная рассылка приучает пользователей игнорировать или блокировать вас.
  • Делайте клики значимыми. Клик должен вести пользователя прямо к нужному контенту, а не просто на главную страницу.

Заключение

JavaScript Notifications API позволяет веб-приложениям своевременно доносить системные сообщения до пользователей — как пока страница открыта, так и после её закрытия, через service worker. Рабочий процесс неизменен: определение возможностей, запрос разрешения в ответ на жест пользователя, затем создание уведомлений с помощью конструктора Notification (или showNotification() в воркере) и реакция на события клика. В сочетании с дисциплинированным и экономным использованием уведомления становятся функцией, которую пользователи оставляют включённой, а не спешат отключить.

Практика

Практика
Какие утверждения точно описывают возможности и лучшие практики JavaScript Notifications API?
Какие утверждения точно описывают возможности и лучшие практики JavaScript Notifications API?
Was this page helpful?