Обмен данных между iframe и родительским сайтом
Быстрый ответ
Чтобы осуществить безопасное двустороннее взаимодействие между iframe и родительской страницей, воспользуйтесь методом window.postMessage()
. Обмен данными из iframe можно инициировать с помощью parent.postMessage(message, targetOrigin)
и со стороны родительского окна через iframe.contentWindow.postMessage(message, targetOrigin)
. Вам необходимо установить обработчик событий, который будет фильтровать принимаемые сообщения, проверять event.origin
и обрабатывать event.data
.
Пример настройки коммуникации:
// От родительского окна к iframe
document.getElementById('myIframe').contentWindow.postMessage('Привет, iframe!', '*');
// Если iframe настроен на прослушивание
window.addEventListener('message', event => {
if (event.origin !== window.location.origin) return;
alert(`Мое родительское окно говорит: ${event.data}`);
}, false);
Для большей безопасности используйте конкретный targetOrigin вместо звездочки '*'
.
Подробное руководство: как обеспечить безопасное взаимодействие между iframe и родительской страницей
Target Origin: небезопасно использовать *
для всех!
Применение '*'
в postMessage()
аналогично открытию всех дверей в вашем доме: сквозь них может пройти кто угодно. Безопаснее использовать конкретный URL для идентификации получателя:
iframe.contentWindow.postMessage('Привет, iframe!', 'https://example.com');
Как установить взаимодействие от iframe к родительской странице
В современных браузерах можно использовать CustomEvent
для организации обратной связи. Отправка сообщений из iframe осуществляется так:
var customEvent = new CustomEvent('owlPost', { detail: 'Сообщение' });
parent.document.dispatchEvent(customEvent);
Родительская страница должна быть готова принять и обработать это событие:
window.addEventListener('owlPost', function(e) {
console.log('Сообщение из ифрейма:', e.detail);
});
Структурирование сообщений при помощи классов
Определите классы для сообщений, добавьте свойства type
и body
, это упростит и структурирует взаимодействие:
class OwlPost {
constructor(type, body) {
this.type = type;
this.body = body;
}
}
Проверка достоверности данных в event.data
Получение сообщения — это только первый шаг. Важно проверять, от кого и какое сообщение пришло:
window.addEventListener('message', event => {
if (event.origin !== 'https://hogwarts.com') return;
if (!event.data.type || !event.data.body) return;
handleOwlPost(event.data);
});
Функция sendMessage для унификации отправки сообщений
Воспользуйтесь функцией sendMessage
, чтобы унифицировать отправку сообщений через разные объекты:
function sendMessage(owl, message, targetOrigin) {
owl.contentWindow.postMessage(message, targetOrigin);
}
Отдельные обработчики событий для разных сообщений
Обработку разных типов сообщений стоит проводить в отдельных функциях:
const owlHandlers = {
'Хедвиг': handleHedwigPost,
'Эррол': handleErrolPost,
};
function handleOwlPost(message) {
if (owlHandlers[message.type]) {
owlHandlers[message.type](message.body);
}
}
Визуализация
Смайлики в схемах лишь добавляют непринужденности в изложении, но объяснение от этого станет не менее понятным.
Остров Родителя (🏝️): Отправляет 💌 с сообщением через океан
Океан iframe (🌊): Переносит 💌 к назначенному получателю
Остров iframe (🏖️): Получает 💌, прочитывает и следует инструкциям
Остров iframe (🏖️): Отправляет 💌 обратно
Остров Родителя (🏝️): В ожидании и реакции на ответ
На что обратить внимание: лучшие методики и инструменты
Совместимость браузеров
Перед тем как использовать postMessage, убедитесь, что нужные вам браузеры поддерживают эту функцию. IE8 и более свежие версии поддерживают этот API, но всегда лучше проверять на веб-сайте Can I use.
Кросс-доменное взаимодействие
Для общения между ифреймами с разных доменов понадобятся дополнительные настройки, а возможно, и использование специального JS-файла, расположенного на CDN, особенно если речь идет о поддоменах.
Категоризация сообщений
Структурируйте сообщения, разделяйте их по типу, источнику и назначению для улучшения взаимодействия.
{
type: 'notification',
source: 'iframe',
purpose: {
message: 'Пользователь согласился с условиями.'
}
}
Безопасность обмена сообщениями
Для обеспечения безопасности можно проверять event.source
и использовать криптографические методы, если требуется сохранить конфиденциальность информации.
Передача сложных данных
Если вам нужно передать сложные данные, пользуйтесь JSON-кодированием, и обязательно обработайте возможные ошибки кодирования:
window.addEventListener('message', event => {
try {
const data = JSON.parse(event.data);
// Обработка данных...
} catch (error) {
console.error('произошла ошибка при разборе данных', error);
}
});
Взаимодействие в реальном времени и частое обмен сообщениями
Для динамического взаимодействия, которое требует многократной передачи данных, оптимизируйте процесс, например, при помощи requestAnimationFrame
.
Полезные материалы
- Политика одного источника – Безопасность в сети | MDN — подробное руководство по взаимодействию между разными доменами, включая iframe.
- HTML Iframes — основы использования iframe в HTML.
- RFC 6454 – Понятие происхождения в вебе — центральная концепция веб-безопасности и политики взаимодействия между доменами.
- HTML Стандарт — официальная документация стандартов HTML, охватывающая тему веб-сообщений.
- Кросс-доменные xmlhttprequest с CORS – Mozilla Hacks — о Cross-Origin Resource Sharing (CORS) и упрощении кросс-доменных запросов.
- Can I use... Таблицы поддержки для HTML5, CSS3 и других технологий — таблицы совместимости для postMessage API.
- Понимание и использование postMessage API — подробное объяснение и практическое применение API postMessage.