Что такое iframe

<iframe> (inline frame) — HTML-тег, загружающий отдельный документ внутри текущей страницы. По сути, это браузер внутри браузера: у вложенного документа свой DOM, свои стили, своя среда выполнения JavaScript.

<iframe
  src="https://payment.example.com/card-form"
  width="100%"
  height="300"
  frameborder="0">
</iframe>

Ключевое свойство: Same-Origin Policy запрещает JavaScript внутри iframe обращаться к DOM, cookie и localStorage родительской страницы, если домены различаются.

Где iframe уместен

Платёжные формы — самый распространённый и обоснованный сценарий. Стандарт PCI DSS требует, чтобы поля ввода данных карты были изолированы от остального кода страницы. Stripe Elements, ЮKassa, CloudPayments — все строят форму на iframe по этой причине.

Видео и медиа — YouTube, Vimeo и VK Video встраиваются только через iframe.

Сторонние чат-боты и виджеты поддержки — изоляция защищает от конфликтов с CSS и JS хост-страницы.

Почему iframe не используется в современных рекомендательных системах

Проблема Последствие
Отдельный HTTP-запрос на iframe-документ Задержка отображения виджета +100–300 мс
Same-Origin Policy блокирует доступ к cookie сессии Рекомендации не знают о профиле авторизованного пользователя
Events внутри iframe не всплывают в родителя Клик на рекомендацию не трекируется автоматически в аналитику
Фиксированная высота Адаптивная сетка товаров требует JS-моста через postMessage
Контент не виден поисковику SEO не получает семантики рекомендаций

Современные платформы персонализации рендерят виджеты напрямую в DOM хост-страницы через JavaScript SDK: контент появляется в потоке страницы, события всплывают нативно, cookie доступны без ограничений.

postMessage: коммуникация через барьер

Единственный стандартный способ передать данные из iframe в родителя — API postMessage. Используется для сообщений об успешной оплате, изменении размера iframe и пользовательских событиях:

// Внутри iframe (payment.example.com)
parent.postMessage({ type: 'payment_success', amount: 1990 }, 'https://shop.ru');

// На родительской странице (shop.ru)
window.addEventListener('message', (event) => {
  if (event.origin !== 'https://payment.example.com') return;
  if (event.data.type === 'payment_success') {
    // обработать подтверждение оплаты
  }
});

Важно: всегда проверяйте event.origin — без проверки любой домен может отправить сообщение в ваш обработчик.

Ограничения третьесторонних cookies в iframe

Начиная с Safari (ITP) и Chrome, третьесторонние cookies внутри iframe по умолчанию заблокированы или будут заблокированы. Это означает: если ваш виджет на widget.vendor.com встроен в iframe на shop.ru, сессионные cookies widget.vendor.com не будут установлены или доступны. Это дополнительный аргумент против iframe для любых виджетов с состоянием.