Push-уведомление может приходить с правильным текстом, но после клика открывать главную, старую вкладку или чужой маршрут. Обычно проблема находится в данных уведомления, обработчике notificationclick или области действия service worker.

Перед исправлением запишите ожидаемый URL, payload и фактическое действие в разных состояниях браузера: вкладка уже открыта, закрыта, приложение установлено или работает как обычный сайт. Один обработчик должен безопасно нормализовать адрес и выбрать focus либо openWindow.

Что проверить в первую очередь

Сначала зафиксируйте наблюдаемое поведение и не меняйте сразу несколько настроек. Важны точное время сбоя, адрес или сценарий, ожидаемый результат и последнее известное рабочее состояние. Так можно отличить причину от случайного совпадения и сохранить возможность быстрого отката.

  • Посмотрите payload до отправки и объект notification.data внутри service worker.
  • Проверьте, какой service worker реально контролирует страницу и каков его scope.
  • Воспроизведите клик при открытой вкладке, закрытом браузере и установленной PWA.
  • Убедитесь, что старый воркер не продолжает обслуживать клиентов после обновления.

Почему возникает проблема

У подобных сбоев редко бывает одна универсальная причина. На итог одновременно влияют конфигурация приложения, окружение, данные, кеш, права и внешние сервисы. Проверка должна идти от внешнего симптома к конкретному уровню, на котором впервые появляется неверное состояние.

  • URL положен в поле payload, которое библиотека не переносит в notification.data.
  • Обработчик всегда вызывает clients.openWindow для главной страницы и игнорирует целевой путь.
  • clients.matchAll находит вкладку, но код фокусирует ее без navigate к нужному адресу.
  • Относительный URL разрешается относительно scope, а не ожидаемого корня сайта.
  • Старый service worker остается активным и выполняет предыдущую логику клика.

Пошаговая диагностика

Диагностику проводите на копии или в контролируемое время. Перед изменениями сохраните конфигурацию, данные и журналы. Каждый шаг должен отвечать на один вопрос и оставлять измеримый результат: код ответа, запись в логе, состояние процесса, значение поля или воспроизводимый тест.

  • Добавьте временный безопасный лог типа события и целевого пути без идентификаторов пользователя.
  • Проверьте регистрацию воркера, scope и список активных/ожидающих версий в DevTools.
  • Сравните структуру payload для фонового и отображаемого браузером уведомления.
  • В notificationclick используйте event.waitUntil и проверьте, завершается ли асинхронная цепочка.
  • Получите clients.matchAll с includeUncontrolled и проанализируйте URL найденных окон.

Правильная логика notificationclick

Обработчик клика должен доверять только разрешенным адресам своего origin и корректно работать как с существующей вкладкой, так и без нее.

  • Сохраните путь в notification.data.url в согласованном формате между сервером и воркером.
  • Создайте URL через new URL(path, self.location.origin) и запретите переход на неожиданный origin.
  • Если подходящая вкладка открыта, вызовите navigate при необходимости и затем focus.
  • Если вкладки нет, откройте clients.openWindow с проверенным абсолютным URL.
  • Закройте notification и верните Promise из event.waitUntil, чтобы браузер дождался действия.

Как исправить проблему

Исправление лучше разбить на небольшие обратимые изменения. После каждого шага повторяйте исходный сценарий и проверяйте соседние функции. Если правка касается данных, сначала выполните ее на ограниченной выборке и сохраните журнал затронутых записей.

  • Унифицируйте схему payload и добавьте версию, тип уведомления и целевой путь.
  • Исправьте обработчик клика с явной нормализацией URL и проверкой origin.
  • Обновите версию service worker, активируйте новую сборку контролируемо и перезагрузите клиенты.
  • Разведите переход для разных типов уведомлений через allowlist маршрутов.
  • Добавьте fallback на безопасную страницу, если данные отсутствуют или маршрут больше не существует.

Безопасный порядок внедрения

  • Сохраните резервную копию затрагиваемых файлов, базы и конфигурации, а также заранее опишите способ отката.
  • Воспроизведите сбой на тестовой записи, учетной записи или отдельном окружении без реальных платежей и рассылок.
  • Вносите по одному логическому изменению, фиксируя его в системе контроля версий или журнале работ.
  • Не отключайте права, проверку входных данных и защитные механизмы только ради исчезновения сообщения об ошибке.
  • После выкладки контролируйте логи, метрики и ключевой пользовательский сценарий, а не только открытие одной страницы.

Как проверить результат

Успешный разовый тест еще не доказывает исправление. Нужны повторный запуск, крайние случаи и проверка после очистки кеша, перезапуска процесса или новой сессии. Для критичных сценариев полезно сохранить автоматический тест или хотя бы короткий регрессионный чек-лист.

  • Каждый тип уведомления открывает нужный маршрут при закрытом и открытом приложении.
  • Клик по уведомлению не создает лишние вкладки, если подходящая вкладка уже есть.
  • Внешний или поврежденный URL не открывается и заменяется безопасным fallback.
  • После обновления все клиенты обслуживает новая версия воркера.

Типичные ошибки при исправлении

  • Передавать в push произвольный полный URL и открывать его без проверки origin.
  • Вызывать async-функцию без event.waitUntil, из-за чего браузер завершает воркер.
  • Использовать skipWaiting без понимания, совместима ли новая версия с открытыми вкладками.
  • Тестировать только при одной открытой вкладке Chrome на компьютере.

Как предотвратить повторение

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

  • Зафиксируйте контракт payload и тестируйте его на сервере и в service worker.
  • Добавьте матрицу браузеров и состояний приложения для push-сценариев.
  • Версионируйте кеш и воркер, показывая пользователю контролируемое обновление.
  • Собирайте обезличенные события доставки и клика с версией обработчика.

Что подготовить для разбора

  • Краткое описание ожидаемого и фактического поведения без паролей, токенов и персональных данных.
  • Точное время и последовательность действий, после которых появляется проблема.
  • Версии приложения, окружения и зависимостей, а также перечень последних изменений.
  • Фрагменты журналов с контекстом до и после ошибки; секреты в них необходимо скрыть.
  • Описание уже выполненных проверок и способ безопасно повторить проблему.

Частые вопросы

Почему открывается главная, хотя URL передан?

Часто поле лежит не в notification.data или старый воркер использует fallback. Нужно проверить фактический объект внутри события, а не только серверный payload.

Нужно ли всегда открывать новую вкладку?

Нет. Если вкладка сайта уже открыта, лучше перевести ее на нужный маршрут и сфокусировать. Новая вкладка нужна, когда подходящего клиента нет.

Когда нужна помощь специалиста

Если push приходит, но переходы работают нестабильно, я могу проверить payload, версии service worker и сценарии focus/openWindow, исправить безопасную маршрутизацию и протестировать уведомления в разных состояниях приложения.