Использование window.postMessage через домены: ошибки и решения
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Функция обмена сообщениями между доменами может быть реализована с помощью метода window.postMessage
. Процесс отправки сообщения выглядит так:
Отправитель (например, из родительского окна):
// Устанавливаем слушатель для получения сообщений
window.addEventListener('message', event => {
if (event.origin !== "http://example.com") return; // Доверяем только сообщениям от проверенных отправителей
// Обрабатываем содержимое event.data после чашки чая ☕
});
Получатель (например, из iframe):
// Отправляем сообщение с теплотой ❤️
parent.postMessage("Привет, мир!", "http://example.com");
Для обеспечения безопасности крайне важно тщательно проверять отправителей и точно указывать адресат сообщения.
Взаимодействие с родителем из iframe
Для обмена данными между страницей и её iframe используйте window.parent
или window.top
:
// Родитель, прими! 🎶
window.parent.postMessage("Сообщение для родителя", "http://parent-domain.com");
window.top.postMessage("Сообщение для верхнего уровня", "http://top-domain.com");
Обязательная проверка входящих сообщений — залог безопасности вашего приложения.
Готовы ли мы к использованию postMessage?
Прежде всего, убедитесь, что браузер поддерживает window.postMessage
. Избегайте использования '*'
в качестве targetOrigin — такой подход небезопасен. Вместо этого всегда конкретизируйте домен получателя:
if (!window.postMessage) alert('К сожалению, ваш браузер устарел!');
Если нужно поддерживать старые браузеры, то стоит обратить внимание на window.attachEvent
.
Субдомены и слеши
Субдомены рассматриваются как отдельные источники. К тому же, важно и правильное использование слешей в URL:
// Правильно
window.postMessage('Привет', 'http://www.domain.com/');
// Неправильно
window.postMessage('Привет', 'http://www.domain.com'); // Это может вызвать ошибки...
Проверяйте URL перед отправкой сообщения.
Визуализация
Для понимания процесса работы window.postMessage
можно привести сравнение с решением головоломки. Вот наглядный пример:
Домен А (🏰): Отправляет зашифрованное сообщение [📩] с особенной печатью (targetOrigin)
Домен В (🌆): Принимает только письма с знакомой печатью
window.postMessage('Шшш... Секретное сообщение', 'https://domainB.com');
// 🏰 👉 🕊️ (несёт 📩) 👉 🌆 (вот оно, давайте рассмотрим 📩)
О безопасности общения:
🏰: "Я признаю только послания с печатью 🌆!"
🌆: "Что за печать? Пусть эту корреспонденцию уничтожат 🔥!"
Рекомендации для безопасного обмена данными:
// 🏰 отправляет защищённое сообщение 🌆, минимизируя риск вмешательства (👤🕵️♂️👤)
window.postMessage('Здравствуй, доверенный домен B!', 'https://domainB.com'); // 📩🛡️
Разбор объекта MessageEvent
Важно разобраться с объектом MessageEvent. Он не является просто ответной посылкой:
window.addEventListener('message', event => {
if (event.origin !== "http://example.com") return;
console.log('Получено что-то крайне важное:', event.data);
console.log('Откуда пришло:', event.origin);
});
Помимо event.data
, анализируйте и event.origin
, чтобы избежать нежелательных сюрпризов.
Проведите тестирование
Чтобы проверить работоспособность ваших скриптов, вставьте iframe с атрибутом src
, указывающим на домен-получатель. Не забудьте протестировать приложение в разных браузерах.
<iframe src="http://example.com/iframe.html"></iframe> <!-- Чем больше тестов, тем надёжнее программное обеспечение. -->
Полезные материалы
- Метод Window: postMessage() – Web APIs | MDN – Отличное руководство по использованию метода
postMessage()
. - javascript – Способы обхода политики одного источника – Stack Overflow – Профессиональные рекомендации по решению проблем обмена данных между доменами.
- Двусторонняя коммуникация с iframe – GitHub Gist – Практическое знакомство с
postMessage()
и доступ к исходному коду в дополнение. - MessageEvent – Web APIs | MDN – Подробное обсуждение интерфейса MessageEvent и его использования с
postMessage()
. - Учебник | DigitalOcean – Загляните в комментарии для подробного руководства по реализации
window.postMessage()
.