Обмен данных между iframe и родительским сайтом

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

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

Чтобы осуществить безопасное двустороннее взаимодействие между iframe и родительской страницей, воспользуйтесь методом window.postMessage(). Обмен данными из iframe можно инициировать с помощью parent.postMessage(message, targetOrigin) и со стороны родительского окна через iframe.contentWindow.postMessage(message, targetOrigin). Вам необходимо установить обработчик событий, который будет фильтровать принимаемые сообщения, проверять event.origin и обрабатывать event.data.

Пример настройки коммуникации:

JS
Скопировать код
// От родительского окна к 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 для идентификации получателя:

JS
Скопировать код
iframe.contentWindow.postMessage('Привет, iframe!', 'https://example.com');

Как установить взаимодействие от iframe к родительской странице

В современных браузерах можно использовать CustomEvent для организации обратной связи. Отправка сообщений из iframe осуществляется так:

JS
Скопировать код
var customEvent = new CustomEvent('owlPost', { detail: 'Сообщение' });
parent.document.dispatchEvent(customEvent);

Родительская страница должна быть готова принять и обработать это событие:

JS
Скопировать код
window.addEventListener('owlPost', function(e) {
    console.log('Сообщение из ифрейма:', e.detail);
});

Структурирование сообщений при помощи классов

Определите классы для сообщений, добавьте свойства type и body, это упростит и структурирует взаимодействие:

JS
Скопировать код
class OwlPost {
    constructor(type, body) {
        this.type = type;
        this.body = body;
    }
}

Проверка достоверности данных в event.data

Получение сообщения — это только первый шаг. Важно проверять, от кого и какое сообщение пришло:

JS
Скопировать код
window.addEventListener('message', event => {
    if (event.origin !== 'https://hogwarts.com') return;
    if (!event.data.type || !event.data.body) return;
    handleOwlPost(event.data);
});

Функция sendMessage для унификации отправки сообщений

Воспользуйтесь функцией sendMessage, чтобы унифицировать отправку сообщений через разные объекты:

JS
Скопировать код
function sendMessage(owl, message, targetOrigin) {
    owl.contentWindow.postMessage(message, targetOrigin);
}

Отдельные обработчики событий для разных сообщений

Обработку разных типов сообщений стоит проводить в отдельных функциях:

JS
Скопировать код
const owlHandlers = {
    'Хедвиг': handleHedwigPost,
    'Эррол': handleErrolPost,
};

function handleOwlPost(message) {
    if (owlHandlers[message.type]) {
        owlHandlers[message.type](message.body);
    }
}

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

Смайлики в схемах лишь добавляют непринужденности в изложении, но объяснение от этого станет не менее понятным.

Markdown
Скопировать код
Остров Родителя (🏝️): Отправляет 💌 с сообщением через океан
Океан iframe (🌊): Переносит 💌 к назначенному получателю
Остров iframe (🏖️): Получает 💌, прочитывает и следует инструкциям 

Остров iframe (🏖️): Отправляет 💌 обратно
Остров Родителя (🏝️): В ожидании и реакции на ответ

На что обратить внимание: лучшие методики и инструменты

Совместимость браузеров

Перед тем как использовать postMessage, убедитесь, что нужные вам браузеры поддерживают эту функцию. IE8 и более свежие версии поддерживают этот API, но всегда лучше проверять на веб-сайте Can I use.

Кросс-доменное взаимодействие

Для общения между ифреймами с разных доменов понадобятся дополнительные настройки, а возможно, и использование специального JS-файла, расположенного на CDN, особенно если речь идет о поддоменах.

Категоризация сообщений

Структурируйте сообщения, разделяйте их по типу, источнику и назначению для улучшения взаимодействия.

JS
Скопировать код
{
    type: 'notification',
    source: 'iframe',
    purpose: {
        message: 'Пользователь согласился с условиями.'
    }
}

Безопасность обмена сообщениями

Для обеспечения безопасности можно проверять event.source и использовать криптографические методы, если требуется сохранить конфиденциальность информации.

Передача сложных данных

Если вам нужно передать сложные данные, пользуйтесь JSON-кодированием, и обязательно обработайте возможные ошибки кодирования:

JS
Скопировать код
window.addEventListener('message', event => {
    try {
        const data = JSON.parse(event.data);
        // Обработка данных...
    } catch (error) {
        console.error('произошла ошибка при разборе данных', error);
    }
});

Взаимодействие в реальном времени и частое обмен сообщениями

Для динамического взаимодействия, которое требует многократной передачи данных, оптимизируйте процесс, например, при помощи requestAnimationFrame.

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

  1. Политика одного источника – Безопасность в сети | MDN — подробное руководство по взаимодействию между разными доменами, включая iframe.
  2. HTML Iframes — основы использования iframe в HTML.
  3. RFC 6454 – Понятие происхождения в вебе — центральная концепция веб-безопасности и политики взаимодействия между доменами.
  4. HTML Стандарт — официальная документация стандартов HTML, охватывающая тему веб-сообщений.
  5. Кросс-доменные xmlhttprequest с CORS – Mozilla Hacks — о Cross-Origin Resource Sharing (CORS) и упрощении кросс-доменных запросов.
  6. Can I use... Таблицы поддержки для HTML5, CSS3 и других технологий — таблицы совместимости для postMessage API.
  7. Понимание и использование postMessage API — подробное объяснение и практическое применение API postMessage.