Фильтр для iframe

Featherlight — лёгкая библиотека для создания модальных окон на базе jQuery. Одним из её преимуществ является гибкость в работе с различным контентом, включая изображения, HTML-элементы и iframe. Работа с iframe требует особого внимания из-за особенностей безопасности и динамического изменения размеров.


Подключение и инициализация

Для корректной работы с iframe требуется подключение jQuery и самой библиотеки Featherlight:

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<link href="https://cdn.rawgit.com/noelboss/featherlight/1.7.14/release/featherlight.min.css" rel="stylesheet">
<script src="https://cdn.rawgit.com/noelboss/featherlight/1.7.14/release/featherlight.min.js"></script>

Инициализация модального окна с iframe осуществляется следующим образом:

$('.open-iframe').featherlight({
    iframe: 'https://example.com',
    iframeWidth: 800,
    iframeHeight: 600
});

Здесь iframeWidth и iframeHeight определяют размер модального окна. Это важно для корректного отображения стороннего контента и предотвращения горизонтальной или вертикальной прокрутки.


Использование фильтров при работе с iframe

Иногда необходимо ограничивать или фильтровать содержимое iframe в зависимости от URL или других параметров. Featherlight предоставляет возможность кастомизации через beforeOpen и afterContent колбэки.

Пример фильтрации по домену:

$('.open-iframe').featherlight({
    iframeWidth: 800,
    iframeHeight: 600,
    beforeOpen: function(event){
        var url = $(this).data('url');
        var allowedDomains = ['example.com', 'trustedsite.org'];

        var domain = (new URL(url)).hostname;
        if (!allowedDomains.includes(domain)) {
            alert('Доступ к этому ресурсу запрещён.');
            return false; // блокирует открытие модального окна
        }

        this.$instance.find('iframe').attr('src', url);
    }
});

Ключевые моменты:

  • beforeOpen позволяет перехватить момент перед открытием модального окна.
  • Проверка домена через URL обеспечивает базовую защиту от загрузки нежелательного контента.
  • Возврат false отменяет открытие модального окна.

Динамическая подстройка размера iframe

Контент iframe может иметь непредсказуемую высоту. Для корректного отображения рекомендуется использовать afterContent:

$('.open-iframe').featherlight({
    iframeWidth: 800,
    afterContent: function(){
        var iframe = this.$instance.find('iframe');
        iframe.on('load', function(){
            try {
                var height = iframe[0].contentWindow.document.body.scrollHeight;
                iframe.css('height', height + 'px');
            } catch(e) {
                iframe.css('height', '600px'); // fallback
            }
        });
    }
});

Объяснение:

  • afterContent выполняется после вставки контента в окно.
  • Использование события load позволяет дождаться полной загрузки страницы внутри iframe.
  • try-catch необходим для обработки ошибок при кросс-доменных iframe, где доступ к contentWindow.document запрещён политикой безопасности.

Передача данных в iframe через URL

Иногда требуется передавать параметры динамически:

$('.open-iframe').featherlight({
    iframeWidth: 800,
    iframeHeight: 600,
    beforeOpen: function(){
        var userId = $(this).data('user-id');
        var url = 'https://example.com/profile?id=' + encodeURIComponent(userId);
        this.$instance.find('iframe').attr('src', url);
    }
});

Особенности:

  • Динамическая генерация URL позволяет безопасно передавать параметры.
  • Использование encodeURIComponent предотвращает ошибки при наличии спецсимволов.

Ограничение действий внутри iframe

Featherlight не контролирует контент iframe напрямую, но можно использовать sandbox-атрибут для ограничения:

$('.open-iframe').featherlight({
    iframeWidth: 800,
    iframeHeight: 600,
    afterContent: function(){
        this.$instance.find('iframe').attr('sandbox', 'allow-scripts allow-same-origin');
    }
});
  • sandbox запрещает всплывающие окна, формы и другие потенциально опасные действия.
  • Указание конкретных флагов (allow-scripts, allow-same-origin) даёт тонкую настройку разрешений.

Автоматическое закрытие iframe при событии внутри контента

Для интерактивных приложений полезно закрывать модальное окно по событию из iframe:

$('.open-iframe').featherlight({
    iframeWidth: 800,
    iframeHeight: 600,
    afterContent: function(){
        var iframe = this.$instance.find('iframe')[0];
        window.addEventListener('message', (event) => {
            if (event.source === iframe.contentWindow && event.data === 'closeModal') {
                this.close();
            }
        });
    }
});

Пояснение:

  • Используется postMessage для безопасной коммуникации между iframe и родительским окном.
  • Проверка event.source гарантирует, что сообщение пришло от нужного iframe.

Практические рекомендации

  1. Всегда фильтровать URL перед вставкой в iframe. Это предотвращает загрузку небезопасного контента.
  2. Использовать sandbox для ограничения действий внутри iframe.
  3. Динамически корректировать размеры через afterContent и событие load, чтобы избежать скроллинга.
  4. Применять postMessage для взаимодействия между iframe и родительским окном.
  5. Не вставлять iframe напрямую через HTML, если нужен контроль фильтров — только через API Featherlight.

Если потребуется, можно детализировать работу с множественными iframe одновременно, включая фильтрацию, динамическое позиционирование и управление событиями между ними. Это особенно важно для сложных приложений с модальными окнами и внешним контентом.