Что такое 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 для любых виджетов с состоянием.