Если страница открывается отдельно, но внутри iframe показывает «refused to connect», сначала посмотрите точную причину в Console браузера. При сообщении о frame-ancestors или X-Frame-Options сервер может исправно отдавать HTML, а браузер — запрещать его встраивание.
Проверять нужно две стороны: кто разрешает разместить документ у себя и кто разрешает встроить сам документ. Ответ HTTP 200 не подтверждает, что виджет работает; исправление принимают на странице, где он должен появиться.
1. Найдите документ, который браузер отказался показать
Откройте DevTools → Network, включите Preserve log и перезагрузите страницу с iframe. Найдите запрос документа фрейма, затем сопоставьте его с сообщением в Console.
Зафиксируйте адрес родительской страницы, исходный src iframe, конечный URL после перенаправлений и статус ответа. Например, виджет мог перенаправить посетителя на страницу входа, у которой встраивание намеренно запрещено: изменение политики исходного URL тогда не поможет.
Если URL не открывается и в отдельной вкладке, сначала разберите сетевую ошибку, TLS или серверный ответ. Надпись «refused to connect» внутри рамки сама по себе не доказывает отказ TCP-соединения.
2. Определите, с какой стороны стоит запрет
frame-ancestors — в ответе встраиваемой страницы
Эта директива Content-Security-Policy перечисляет источники, которым разрешено встраивать документ. Значение 'none' запрещает встраивание, а 'self' ограничивает его собственным origin — сочетанием схемы, хоста и порта.
Условный пример для ответа страницы виджета:
Content-Security-Policy: frame-ancestors 'self' https://portal.example;
Здесь разрешён портал с указанным origin. Это фрагмент настройки: его нужно согласовать с действующей CSP, сохранив остальные ограничения, а не заменить всю политику одной строкой.
При вложенности «портал → оболочка → виджет» проверьте всех предков виджета: разрешения только для ближайшей оболочки недостаточно. Директива не наследует запрет из default-src и не работает через HTML-тег meta. Эти особенности описаны в справочнике frame-ancestors.
X-Frame-Options — тоже в ответе встраиваемой страницы
DENY запрещает показ в любом фрейме. SAMEORIGIN требует одинакового origin у документа и всех его предков; похожие имена доменов не делают их одним origin.
Устаревшее ALLOW-FROM не подходит для разрешения партнёрского домена в современных браузерах. Заголовок нельзя настроить атрибутом iframe или meta-тегом: см. X-Frame-Options.
При действующей CSP с frame-ancestors современные браузеры применяют её вместо X-Frame-Options. Это правило относится к принудительной политике, а не просто к отчётному заголовку Content-Security-Policy-Report-Only: спецификация CSP.
frame-src — в политике родительской страницы
Если Console называет frame-src, проверяйте CSP страницы, содержащей iframe. Она задаёт, откуда эта страница может загружать фреймы; при отсутствии frame-src браузер проверяет child-src, затем default-src. Разрешение со стороны виджета не отменяет запрет со стороны родителя. См. описание frame-src.
3. Найдите слой, который добавляет заголовок
В Network откройте Response Headers именно конечного документа. Для публичного URL можно отдельно посмотреть ответы GET:
curl -sS -L --max-redirs 5 -D - -o /dev/null 'https://widget.example/embed'
Адрес условный: замените его своим публичным URL без токенов. Команда показывает заголовки цепочки, но не выполняет браузерные политики и не повторяет авторизованную сессию.
Сравните фактический ответ с настройками приложения, веб-сервера и CDN. Если политика приходит несколько раз, добавление ещё одной разрешающей CSP не снимает ограничения другой: найдите и исправьте источник конфликта. После изменения проверьте свежий ответ без браузерного кэша и учтите кеширование на CDN.
4. Исправьте разрешение только для нужной интеграции
Если вы управляете встраиваемой страницей, согласуйте список разрешённых родительских origin и примените правило к нужному маршруту. Не открывайте встраивание для всех сайтов ради исчезновения ошибки: ограничения защищают в том числе от подмены интерфейса при кликах.
Если документ принадлежит внешнему сервису, используйте его официальный embed-адрес или согласуйте интеграцию с владельцем. Когда поставщик запрещает iframe, обычная ссылка на страницу может быть корректным решением; отключение защиты браузера посетителей не исправляет интеграцию.
Добавление Access-Control-Allow-Origin не отменяет frame-ancestors и X-Frame-Options. Если Console указывает на CORP или COEP, перейдите к диагностике ERR_BLOCKED_BY_RESPONSE: это другая ветка проверки.
5. Проверьте результат в исходном сценарии
Повторите открытие с той же родительской страницы и через всю цепочку вложенных фреймов. Убедитесь, что виден ожидаемый документ, исчезло конкретное сообщение о блокировке и работает нужное действие внутри виджета.
Если документ уже появился, но авторизация или кнопки не работают, отдельно исследуйте cookie и sandbox: разрешение встраивания не гарантирует работоспособность приложения. На подконтрольном тестовом origin вне списка также проверьте, что нежелательное встраивание осталось запрещено.
Мониторинг Web-Puls помогает следить за доступностью публичного URL, но успешная HTTP-проверка не заменяет этот браузерный сценарий.
Если источник конфликтующих заголовков неясен, отправьте заявку на диагностику. Укажите публичные адреса родителя и виджета, текст ошибки, конечный URL и последние изменения; не передавайте cookie, пароли и ссылки с токенами. Специалист оценит вводные и согласует формат работ.