Подія message в JavaScript — обмін даними між вікнами


Загальний опис

Подія message використовується для обміну повідомленнями між різними вікнами браузера або фреймами, зокрема для роботи з postMessage. Це дозволяє безпечно передавати дані між документами на різних сторінках або вкладках, навіть якщо вони розміщені на різних доменах.

Щоб відправити повідомлення, використовується метод window.postMessage(). Цей метод приймає два аргументи: самі дані для передачі і рядок з доменом, до якого адресується повідомлення. Отримане повідомлення обробляється за допомогою події message, яка запускається на отримуючому кінці.

Коли спрацьовує подія message, доступний об'єкт події, який містить кілька корисних властивостей:

  • data: містить дані, передані відправником.
  • origin: рядок, що вказує на походження сторінки, з якої надійшло повідомлення.
  • source: вказує на вікно або фрейм, що відправив повідомлення.

Важливо перевіряти властивість origin, щоб бути впевненим, що повідомлення надійшло з очікуваного джерела. Це запобігає потенційним атакам, оскільки postMessage може використовуватися для міждоменної взаємодії.

Ось приклад використання message для отримання даних:

window.addEventListener('message', function(event) {
  if (event.origin !== 'https://trusted-origin.com') {
    return; // ігнорування повідомлень від неперевірених джерел
  }
  console.log('Отримано повідомлення:', event.data);
});

У цьому прикладі повідомлення отримуються тільки з конкретного домену, що запобігає можливим проблемам безпеки.

Щоб надіслати повідомлення, код на іншій сторінці може виглядати так:

window.postMessage('Привіт!', 'https://trusted-origin.com');

Отже, message — це ефективний і безпечний спосіб обміну даними між різними вікнами чи фреймами в межах веб-застосунку.

автор: Bond

Порада

Подія message може бути корисною для взаємодії з iframe. Наприклад, ви можете відправити команду в iframe для того, щоб змінити контент або виконати якусь дію всередині нього, не перезавантажуючи сторінку.

автор: Bond
Порада

Під час роботи з postMessage корисно додавати перевірки на тип даних. Наприклад, перед обробкою повідомлення перевіряйте, чи є дані у форматі, який ви очікуєте, особливо якщо повідомлення можуть бути відправлені з різних частин вашої програми.

автор: Bond
Порада

Використовуйте метод event.stopPropagation() у випадку, коли не хочете, щоб подія message поширювалася на інші об'єкти або елементи на сторінці, які також можуть прослуховувати події повідомлень.

автор: Bond

Синтаксис

window.addEventListener('message', function(event) {
  // Обробка повідомлення
});

Переглядачі

Підтримка: стаціонарні переглядачі
Переглядач Google Chrome Mozilla Firefox Apple Safari Opera Microsoft EDGE
66 57 11.1 53 16
Підтримка: мобільні переглядачі
Переглядач Mobile Google Android Mobile Google Chrome Mobile Mozilla Firefox Mobile Apple Safari
66 66 57 11.3
Підтримка: серверні переглядачі
Переглядач Node.js Deno
15.0.0 1.0

Приклади

+ запропонувати свій приклад у пісочниці

Цей приклад демонструє, як подія message дозволяє головній сторінці та iframe обмінюватися повідомленнями, відправляючи та отримуючи їх для асинхронної взаємодії між вікнами.

HTML

<header>
  <h2 class="title">Подія message</h2>
  <p class="description">Використовується для обміну повідомленнями між головною сторінкою та iframe</p>
</header>
<main>
  <div class="result">
    <!-- Форма для надсилання повідомлення до iframe -->
    <input type="text" id="messageInput" placeholder="Введіть повідомлення" />
    <button id="sendMessageButton">Надіслати повідомлення</button>
    
    <!-- Поле для відображення отриманих повідомлень -->
    <p id="messageOutput">Відповідь від iframe буде тут.</p>
    
    <!-- Вбудований iframe -->
    <iframe id="receiverFrame" srcdoc="
      <html>
      <body>
        <p id='receivedMessage'>Очікую на повідомлення...</p>
        <script>
          window.addEventListener('message', function(event) {
            // Відображення отриманого повідомлення
            document.getElementById('receivedMessage').innerText = 'Отримано повідомлення: ' + event.data;
            // Відправка підтвердження назад до головної сторінки
            event.source.postMessage('Повідомлення отримано!', event.origin);
          });
        </script>

CSS

body {
  font-size: 16px;
  line-height: 1.5;
  font-family: monospace;
}

header {
  background-color: #f1f1f1;
  margin-bottom: 25px;
  padding: 15px;
  -webkit-box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
  -moz-box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
  box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
}

header h2.title {
  padding-bottom: 15px;
  border-bottom: 1px solid #999;
}

header p.description {
  font-style: italic;
  color: #222;
}

.result {
  background-color: #f8f8f8;
  padding: 15px;
  min-height: 150px;
  -webkit-box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
  -moz-box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
  box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
  position: relative;
}

input#messageInput, button#sendMessageButton {
  display: inline-block;
  margin-top: 10px;
  padding: 8px;
}
автор: Bond

Цей приклад демонструє простий обмін даними між двома вкладками браузера. Перша вкладка надсилає повідомлення, яке приймається і обробляється у другій вкладці.

// Відправник
window.postMessage('Привіт від вкладки 1!', '*');

// Одержувач
window.addEventListener('message', function(event) {
  console.log('Повідомлення з іншої вкладки:', event.data);
});
автор: Bond

Цей приклад ілюструє, як за допомогою postMessage можна взаємодіяти з вмістом iframe. Головне вікно надсилає команду для оновлення контенту iframe, і відповідний код в iframe реагує на це повідомлення.

// Слухач повідомлень; між вікнами принцип той самий
window.addEventListener('message', function (event) {
    console.log('Отримано повідомлення:', event.data);
});

// Відправлення (другий аргумент — очікуване походження одержувача)
window.postMessage('Онови контент', '*');
автор: Bond

Коментарі

Коментарів ще немає — будьте першим!

Відповідь для

Як форматувати текст?
Пишемо Виходить
**важливо**
*акцент*
~~застаріле~~
Виділення в тексті. Те саме роблять кнопки панелі, що спливає над виділеним.
## Як працює каскад
### Порядок оголошень
Заголовки всередині тексту. Найбільший не потрібен — він у сторінки вже є.
[[css/property/color]] Посилання на сторінку довідника. Наберіть [[ — поле веде сходинками (розділ → тип → сторінка), а хибний ключ підкреслить хвилею.
[[!sandbox/S0oh1hBm]] Живий приклад окремим рядком — саме вікно результату. Той самий ключ зі знаком !: наберіть [[! і дійдіть сходинками до потрібної сторінки, список покаже її приклади.
[MDN](https://developer.mozilla.org) Посилання на чужий сайт.
![Схема каскаду](https://site.com/схема.png) Картинка. Опис обов'язковий: його читають пошуковик і незрячі.
Задайте `display: grid` контейнеру Код усередині речення.
```css
.card { display: grid }
```
Код блоком. Мова після трьох лапок вмикає підсвітку.
- Походження
1. Походження
Перелік: маркований і нумерований.
- [ ] дописати приклади
- [x] перевірити в Firefox
Перелік завдань із галочками. Пробіл у порожніх дужках обов'язковий.
> Порядок важить лише за рівної ваги. Цитата на всю ширину абзацу.
Специфічність
: вага селектора; більша перемагає
Список означень: термін, а під ним пояснення з відступом. Пробіл після двокрапки обов'язковий.
Каскад має три критерії[^1]
[^1]: Походження, специфічність, порядок.
Виноска: номер у тексті, примітка внизу сторінки. Без згадки [^1] у тексті примітка не з'явиться.
Відповідь: ||сорок два|| Ховає те, що між рисками: читач бачить на цьому місці розмиту пляму, а решта речення лишається звичайною. Клац — і текст відкрито.
|| Показати рішення
Задайте контейнеру `display: grid`.
||
Ховає цілі абзаци. На сторінці видно лише підпис із першого рядка («Показати рішення»), решта розгортається клацанням по ньому. Закривні риски — окремим рядком.
Порожній рядок Новий абзац. Щоб перенести рядок усередині абзацу, поставте \ в його кінці.

Увійдіть — коментар з'явиться одразу, без капчі й очікування перевірки.

Правка
Зворотний зв'язок
Вхід