Коротка відповідь
seniorБраузер визначає можливість спілкування між вкладками через політику Same-Origin Policy (SOP) і API, такі як postMessage або BroadcastChannel. Якщо обидві вкладки мають однаковий origin, вони можуть безпосередньо взаємодіяти; у протилежному випадку потрібен postMessage для безпечного обміну даними.
Повне пояснення
Що це і навіщо
Same-Origin Policy (SOP) обмежує доступ скриптів до ресурсів, що мають різний origin (scheme + host + port). Це запобігає XSS‑атак і несанкціонованому доступу.
Ключові принципи
- Origin – унікальний ідентифікатор ресурсу.
- Same-origin – однаковий origin → повний доступ до DOM, localStorage тощо.
- Cross-origin – різні origins → обмежений доступ, потрібен спеціальний механізм.
Як це працює
- При завантаженні сторінки браузер визначає origin.
- Якщо скрипт намагається звернутися до ресурсу з іншого origin, SOP блокує доступ.
- Для дозволеного спілкування між вкладками використовуються API:
- postMessage – надсилає повідомлення між окремими вікнами/вкладками.
- BroadcastChannel – простий спосіб розповсюдження повідомлень між усіма вкладками того ж origin.
Практика і реалізація
// Вкладка A
const channel = new BroadcastChannel('chat');
channel.postMessage({ text: 'Привіт' });
// Вкладка B
const channel = new BroadcastChannel('chat');
channel.onmessage = e => console.log(e.data.text);
Тестування
Для unit‑тестів можна мокати BroadcastChannel або використовувати бібліотеку jsdom з підтримкою postMessage. При інтеграційному тестуванні Playwright дозволяє відкривати кілька вкладок і перевіряти обмін.
Безпека
- Перевіряйте
event.originуonmessage‑обробнику. - Не довіряйте даним без валідації.
Альтернативи
- localStorage events – старий спосіб, але працює лише між вкладками одного origin.
- Service Workers – можуть пересилати повідомлення через
postMessageміж вкладками і воркерами.
Часті помилки
- Забудьте перевірити
event.origin→ XSS. - Використання
BroadcastChannelбез перевірки підтримки браузера → помилка. - Неправильний ключ каналу → повідомлення не доходять.
- Надмірне використання
postMessage→ продуктивність. - Неочікувані типи даних → помилки парсингу.
- Відсутність
close()→ витік пам’яті. - Перевищення розміру повідомлення (≈64 KB) → обірвані дані.
- Необхідність CORS‑заголовків при fetch між origin → блокування.
Cheatsheet
- postMessage:
window.postMessage(message, targetOrigin). - BroadcastChannel:
new BroadcastChannel(name)→channel.postMessage(msg),channel.onmessage. - Перевірка origin:
if (event.origin !== expectedOrigin) return;.