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, исправить безопасную маршрутизацию и протестировать уведомления в разных состояниях приложения.