Использование postMessage в HTML5: связь iframe и родительского окна

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для осуществления взаимодействия из iframe к родительскому окну применяется метод postMessage. Ниже представлен пример кода для дочернего iframe:

JS
Скопировать код
// Риторический стук в дверь главного модуля
parent.postMessage('Привет, родитель!', 'https://parent-domain.com');

В родительском окне требуется настроить обработчик для приема сообщений:

JS
Скопировать код
window.addEventListener('message', (event) => {
    if (event.origin === 'https://iframe-domain.com') { // родитель уверен, что сигнал от надежного источника
        console.log('Слышу тебя, дочка:', event.data);
    }
});

Укажите реальные URL вашего сайта вместо примеров доменов. Данный метод гарантирует безопасное и кроссбраузерное взаимодействие.

Кинга Идем в IT: пошаговый план для смены профессии

Лучшие практики безопасного обмена данными

Всегда проверяйте источник

Не забывайте про кросс-проверку event.origin в обработчике событий сообщений – это ключевой момент для обеспечения безопасности.

JS
Скопировать код
if (event.origin !== 'https://trusted-source.com') {
    // Наш "чувство опасности" всегда должно быть включено
    return;
}

Удаление обработчиков событий

В React очистка обработчиков событий необходима, чтобы предотвратить утечки памяти при демонтировании компонентов:

JS
Скопировать код
useEffect(() => {
  const messageHandler = (event) => { /* ... обработка сообщения ... */ };
  window.addEventListener('message', messageHandler);

  return () => { // Время для генеральной уборки
    window.removeEventListener('message', messageHandler);
  };
}, []);

Управление состоянием в сложных приложениях

В сложных приложениях управление состоянием становится вершиной мастерства. Здесь Redux может стать вашим надежным помощником в контролировании изменений состояния, вызванных сообщениями из iframe.

Поддержка PostMessage браузерами

Проверка поддержки postMessage

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

Улучшение совместимости обработчиков событий

Чтобы обеспечить лучшую совместимость, особенно с Internet Explorer 8 и более старыми версиями, добавляйте обработчики событий с учетом возможностей браузера (addEventListener против attachEvent).

JS
Скопировать код
function addEvent(element, event, handler) {
  if (element.addEventListener) { // Путь для современных браузеров
    element.addEventListener(event, handler, false);
  } else if (element.attachEvent) { // Добро пожаловать в мир IE8!
    element.attachEvent('on' + event, handler);
  }
}

addEvent(window, 'message', messageHandler);

Осторожно, ловушки! И как их избежать

Избегайте использования "*" для targetOrigin

Использование '*' в методе postMessage(targetOrigin) может казаться простым решением, но оно небезопасно. Желательно указывать точный источник.

Не забывайте о дополнительной проверке источника сообщения

Для повышения безопасности осуществляйте проверку не только event.origin, но и event.source, сравнивая его с ожидаемым iframe.

Контроль за обработчиками сообщений

Если вас буквально заваливают сообщениями postMessage, применяйте debouncing или throttling для оптимизации обработчика.

JS
Скопировать код
let timeout; // готовы принять поток сообщений
window.addEventListener('message', (event) => {
  clearTimeout(timeout); // Предотвращаем предыдущие вызовы
  timeout = setTimeout(() => { // И делаем новую паузу
    // Здесь происходит обработка сообщения
  }, 200);
});

Визуализация

Ситуация примерно такова:

Markdown
Скопировать код
Родительское окно: Управляющий центр
Дочерний iframe: Космонавт

// Космонавт докладывает ситуацию в Управляющий центр
Космонавт зовет Управление: "Хьюстон, у нас проблема! 👨‍🚀"

Это аналогично следующему коду:

JS
Скопировать код
// В коде: iframe обращается к Родительскому окну
childWindow.postMessage('Хьюстон, у нас проблема!', 'https://mission-control.com');

Управляющий центр (родитель) прислушивается только к проверенным сообщениям (совершается проверка домена) от космонавта (iframe), что обеспечивает безопасность обмена данными в бескрайнем пространстве интернета. 🌌🛰️

Полезные ссылки и практические советы

Учитывайте опыт предшественников

Полезно ознакомиться с библиотеками, абстрагирующими postMessage, например для React. Они предлагают готовые шаблоны и упрощают реализацию.

Руководство по работе с системой

Для более подробной информации изучите документацию postMessage на MDN Web Docs.

Берегите свои данные

При отправке данных в формате JSON, проверьте использование JSON.stringify для сериализации и JSON.parse для десериализации. Это поможет предотвратить случайное выполнение кода и Javascript-внедрения.

Полезные материалы

  1. Window: метод postMessage() – Веб-API | MDN – описание API postMessage и полезные рекомендации по его применению.
  2. HTML Стандартосновная спецификация HTML, включающая API для работы с сообщениями.
  3. HTML5 window.postMessage – подробности о взаимодействии между iframe и родительским окном через postMessage.
  4. GitHub – davidjbradshaw/iframe-resizerбиблиотеки и примеры использования postMessage и адаптивных размеров iframe.
  5. Can I use... Support tables for HTML5, CSS3, etc – информация о совместимости postMessage с разными браузерами.
  6. Междоменное общение с использованием postMessage – SitePoint – глубокое руководство по безопасному и эффективному применению postMessage.