Как организовать общение между двумя вкладками одного приложения в браузере?
Что проверяют
Знаете ли вы современный способ и понимаете ли ограничения: общение возможно только в пределах одного источника.
Как отвечать
Основной инструмент это канал вещания:
const channel = new BroadcastChannel("auth");
channel.postMessage({ type: "logout" });
channel.onmessage = (e) => { if (e.data.type === "logout") redirectToLogin(); };Он создан ровно для этой задачи: сообщения приходят во все вкладки, кроме отправителя, данные передаются структурным клонированием, никакого хранилища не задействовано.
Альтернативы и когда они уместны:
- событие
storage: срабатывает в других вкладках при записи в локальное хранилище. Работает везде, включая старые браузеры, и заодно оставляет состояние на диске. Минусы: событие не приходит в саму вкладку-источник, значения только строковые, а на запись срабатывает даже одинаковое значение не всегда; SharedWorker: общий поток для всех вкладок, удобен, когда нужно одно соединение с сервером на всё приложение;- сервис-воркер: может рассылать сообщения клиентам, полезен вместе с push-уведомлениями и фоновой синхронизацией;
- сервер: если вкладки открыты на разных устройствах, обмен всё равно идёт через сервер, а не между вкладками.
Типичные задачи: разлогинить все вкладки сразу, синхронизировать корзину или тему оформления, не дублировать одинаковые запросы, выбрать «главную» вкладку, которая держит соединение.
Ограничения назовите сами: только один источник (протокол, домен, порт), вкладка в фоне может быть заморожена браузером, а анонимный режим изолирован.
Где спотыкаются
Опрашивают локальное хранилище таймером вместо подписки на событие.
Ждут, что отправитель тоже получит своё сообщение через канал вещания.
Пытаются связать вкладки разных доменов, что запрещено политикой источника.