Преодоление «Отображение запрещено X-Frame-Options»


420

Я пишу крошечную веб-страницу, цель которой состоит в том, чтобы создать несколько других страниц, просто объединяя их в одно окно браузера для удобства просмотра. На нескольких страницах, которые я пытаюсь создать, запрещается создание рамок, и выдается «Отказ от отображения документа, потому что отображение запрещено X-Frame-Options». ошибка в Chrome. Я понимаю, что это ограничение безопасности (по уважительной причине), и у меня нет доступа для его изменения.

Есть ли какой-нибудь альтернативный способ кадрирования или не кадрирования для отображения страниц в одном окне, которые не будут отключены заголовком X-Frame-Options?


117
Если это ваши страницы, то удалите ограничитель кадров. В противном случае, уважайте пожелания автора страницы и НЕ ОФОРМЛЯЙТЕ ИХ.
Марк Б,

Если вы получаете эту ошибку для приложения Facebook и используете вызовы AJAX, я где-то читал, что Facebook действительно нравится использовать теги # для контакта ajax, поэтому попробуйте изменить ссылки, сработало для меня.
eric.itzhak

28
@MarcB Chrome и Firefox этически создают не принадлежащие веб-сайты в собственном пользовательском интерфейсе Chrome. Эти программы также позволяют владельцам, FWIW, применять непринужденную политику одного и того же происхождения. Как сказал garen-checkly: «Я пишу крошечную веб-страницу, цель которой - создать несколько других страниц, просто объединить их в одном окне браузера для удобства просмотра». Это в основном расширяет веб-браузер и будет полностью этичным. Заявленное намерение ничем не отличается от написания bash-скрипта для открытия и размещения окон браузера.
Самуэль Дэниелсон

1
Проверьте Surfly . Он может делать именно то, что вам нужно.
Муодов

1
@MarcB Это не полезно. ОП может не заботиться о пожеланиях автора страницы.
flarn2006

Ответы:


211

У меня была похожая проблема, когда я пытался отобразить контент с нашего собственного сайта в iframe (как диалог в стиле лайтбокса с Colorbox ) и где у нас был общесерверный заголовок «X-Frame-Options SAMEORIGIN» на исходный сервер не позволяет загрузить его на наш тестовый сервер.

Кажется, это нигде не задокументировано, но если вы можете редактировать страницы, которые вы пытаетесь встроить (например, это ваши собственные страницы), просто отправка другого заголовка X-Frame-Options с любой строкой вообще отключает команды SAMEORIGIN или DENY.

например. для PHP, положить

<?php
    header('X-Frame-Options: GOFORIT'); 
?>

в верхней части вашей страницы браузеры объединят два, что приведет к заголовку

X-Frame-Options SAMEORIGIN, GOFORIT

... и позволяет загрузить страницу в фрейме. Похоже, это работает, когда начальная команда SAMEORIGIN была установлена ​​на уровне сервера, и вы хотите переопределить ее в постраничном случае.

Всего наилучшего!


3
У меня была рамка вокруг сайта. На моем сайте я перенаправляю в Instagram для OAUTH. Поскольку Instagram отправляет, X-Frame-Options: SAMEORIGINнет способа сделать это внутри фрейма. Вы должны использовать всплывающее окно.
Стив Таубер

16
С PHP, вероятно, лучше использовать новую header_removeфункцию, если она у вас есть (> = 5.3.0).
кот

11
Или вы можете отредактировать .htaccess, если хотите удалить X-Frame-Options из всего каталога. Просто добавьте строку:Header always unset X-Frame-Options
Джей

4
@cawecoy: Ну да, суть в том, что это недействительно. Он полагается на то, что браузеры игнорируют неверный заголовок и «не открываются», что является неопределенным поведением и довольно хитроумно на него полагаться. GOFORIT(или другой случайный произвольный неверный токен) намеренно нарушает меру безопасности, применяемую сервером; если вы сами управляете сервером (что вы должны делать для любой реальной общедоступной службы), то правильной вещью будет то, что сервер просто не устанавливает заголовок.
Бобинц

31
Похоже, это больше не работает в Chrome. Недопустимые значения приводят к тому, что значение по умолчанию равно DENY.
jamesfm

159

Если вы получаете эту ошибку для видео YouTube, вместо использования полного URL-адреса используйте URL-адрес для встраивания из параметров общего доступа. Это будет выглядетьhttp://www.youtube.com/embed/eCfDxZxTBW4

Вы также можете заменить watch?v=с embed/таким http://www.youtube.com/watch?v=eCfDxZxTBW4становитсяhttp://www.youtube.com/embed/eCfDxZxTBW4


14
О, прогресс ... Я хотел бы, чтобы они просто перенаправили нас на страницу для встраивания, вместо того, чтобы вызывать ошибку и заставлять меня переписывать свои сценарии!
Joeytwiddle

122

Если вы получаете эту ошибку при попытке встроить карту Google в iframe, вам необходимо добавить &output=embedссылку на источник.


120
Это верно только для встраивания карт Google в iframe, а не для общего «решения».
Бенджамин Вольвенд,

17
Мне нужно было вставить карту Google в лайтбокс, так что это «решение» было идеальным
yitwail

5
Если вы пытаетесь сделать это с намерением в сети Twitter, забудьте об этом. Просто потерял весь день, пробуя разные плагины лайтбокса, только чтобы выяснить это: «Хотя вы можете предоставлять ссылки на намерения в IFRAME и виджетах, результирующие страницы не могут быть загружены в IFRAME». Источник: сайт Твиттера.
Губатрон

6
Это не работает, если вы пытаетесь загрузить iframe src после загрузки остальной части страницы, даже если вы добавляете&output=embed
pathfinder

1
@pathfinder Это сработало для меня, когда у меня были проблемы с загрузкой iframe src после загрузки страницы
Дэвид Сайкс

61

UPDATE 2019: Вы можете шунтирование X-Frame-Optionsв <iframe>использовании только на стороне клиента JavaScript , и мой X-Frame-байпас Web Component. Вот демо: Хакер Новости вX-Frame-Bypass . (Проверено в Chrome и Firefox.)


3
Это интересный обходной путь. Хорошо работает в FF / Chrome / Opera, но не работает в IE / Edge. Кто-нибудь, кто знает что-то, что будет?
Коллекционер

7
Это больше не работает. Он выдает « Отказ от отображения« news.ycombinator.com »в кадре, поскольку для параметра« X-Frame-Options »установлено значение« DENY ».» как и ожидалось
g.pickardou

2
@ g.pickardou У меня работает в Google Chrome 46, я вижу Hacker News в iframe.
ниутех

1
@niutech, что скрипка работает после перезагрузки страницы в Chrome 64, но при первой загрузке страницы она не работает. (Попробуйте инкогнито.)
Карл Уолш

1
Спасибо, это круто!
Эндрю Ганс

23

Добавление

  target='_top'

чтобы моя ссылка во вкладке facebook исправила проблему для меня ...


1
У меня была такая же проблема с iframe Paypal, который содержится в другом iframe. Это работает сейчас! Спасибо
Фабрицио Фортино

4
Я также добавил target = '_ top', но проблема с этим решением в том, что теперь ссылка открывается за пределами iframe в новой вкладке без холста facebook.
sumitkanoje

23

Существует плагин для Chrome, который удаляет эту запись заголовка (только для личного использования):

https://chrome.google.com/webstore/detail/ignore-x-frame-headers/gleekbfjekiniecknbkamfmkohkpodhe/reviews


@aup Вероятно, он вносит некоторые изменения в заголовок веб-страницы.

Расширение не вносит никаких изменений в веб-страницу, но, похоже, игнорирует проверку заголовка ответа фрейма на уровне браузера
Vignesh Ammasi


13

У меня была такая же проблема, когда я пытался встроить Moodle 2 в iframe, решение Site administration ► Security ► HTTP securityи проверитьAllow frame embedding


хорошо сделано для метода Moodle, так как другие методы терпят неудачу / перезаписываются.
ericosg

7

Это решение, ребята!

FB.Event.subscribe('edge.create', function(response) {
    window.top.location.href = 'url';
});

Единственное, что сработало для приложений Facebook!



6

Решение для загрузки внешнего веб-сайта в iFrame, даже если параметр x-frame отключен на внешнем веб-сайте.

Если вы хотите загрузить другой сайт в iFrame, и вы получите Display forbidden by X-Frame-Options” ошибку, вы можете фактически преодолеть это, создав прокси-скрипт на стороне сервера.

srcАтрибут плавающего фрейма может иметь URL вида:/proxy.php?url=https://www.example.com/page&key=somekey

Тогда proxy.php будет выглядеть примерно так:

if (isValidRequest()) {
   echo file_get_contents($_GET['url']);
}

function isValidRequest() {
    return $_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['key']) && 
    $_GET['key'] === 'somekey';
}

Это обходит блок, потому что это всего лишь запрос GET, который также мог бы быть обычным посещением страницы браузера.

Имейте в виду: вы можете улучшить безопасность в этом скрипте. Потому что хакеры могут начать загрузку на веб-страницах через ваш прокси-скрипт.


Я делал это несколько недель назад, и любые относительные URL, используемые на внешней странице, не работают при использовании echo. (Как правило, CSS и / или JS, поэтому вы можете не получить полную функциональность, если не измените URL-адреса перед отображением.) Если только я не пропустил что-то ...,
ultrageek

Не уверен, почему это происходит для вас ... Он должен работать как обычный HTTP-запрос, так же, как конечный пользователь будет выполнять при посещении URL. Таким образом, результатом get_file_contents () должна быть полностью рабочая HTML-страница.
Флорис

5

Я перепробовал почти все предложения. Однако единственное, что действительно решило проблему, было:

  1. Создайте .htaccessв той же папке, где лежит ваш файл PHP.

  2. Добавьте эту строку в htaccess:

    Header always unset X-Frame-Options

Встраивание PHP с помощью iframe из другого домена должно работать позже.

Кроме того, вы можете добавить в начало вашего файла PHP:

header('X-Frame-Options: ALLOW');

Что, однако, не было необходимости в моем случае.


Заголовок, всегда отключенный X-Frame-Options в htaccess,
помог

4

У меня была такая же проблема с MediaWiki, это было потому, что сервер запретил встраивание страницы в iframe по соображениям безопасности.

Я решил это писать

$wgEditPageFrameOptions = "SAMEORIGIN"; 

в файл конфигурации MediaWiki PHP.

Надеюсь, поможет.


3

FWIW:

У нас была ситуация, когда нам нужно было убить нашего, iFrameкогда появился этот код «взломщика». Итак, я использовал PHP, function get_headers($url);чтобы проверить удаленный URL, прежде чем показывать его в iFrame. Для повышения производительности я кэшировал результаты в файл, чтобы не устанавливать HTTP-соединение каждый раз.


3

Я использовал Tomcat 8.0.30, ни одно из предложений не сработало для меня. Поскольку мы собираемся обновить X-Frame-Optionsи установить его ALLOW, вот как я настроил разрешение на встраивание iframes:

  • Перейдите в каталог Tomcat conf, отредактируйте файл web.xml
  • Добавьте фильтр ниже:
<filter>
            <filter-name>httpHeaderSecurity</filter-name>
            <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
                   <init-param>
                           <param-name>hstsEnabled</param-name>
                           <param-value>true</param-value>
                   </init-param>
                   <init-param>
                           <param-name>antiClickJackingEnabled</param-name>
                           <param-value>true</param-value>
                   </init-param>
                   <init-param>
                           <param-name>antiClickJackingOption</param-name>
                           <param-value>ALLOW-FROM</param-value>
                   </init-param>
            <async-supported>true</async-supported>
       </filter>

       <filter-mapping>
                   <filter-name>httpHeaderSecurity</filter-name>
                   <url-pattern>/*</url-pattern>
                   <dispatcher>REQUEST</dispatcher>
       </filter-mapping> 
  • Перезапустите сервис Tomcat
  • Доступ к ресурсам с помощью iFrame.

2

Единственный вопрос, который имеет кучу ответов. Добро пожаловать в руководство, которое мне хотелось бы иметь, когда я боролся за это, чтобы заставить его работать в 10:30 ночи в последний день ... FB делает некоторые странные вещи с приложениями Canvas, и, ну, вы были предупреждены. Если вы все еще здесь и у вас есть приложение Rails, которое появится за Facebook Canvas, вам понадобится:

Gemfile:

gem "rack-facebook-signed-request", :git => 'git://github.com/cmer/rack-facebook-signed-request.git'

конфиг / facebook.yml

facebook:
  key: "123123123123"
  secret: "123123123123123123secret12312"

конфиг / application.rb

config.middleware.use Rack::Facebook::SignedRequest, app_id: "123123123123", secret: "123123123123123123secret12312", inject_facebook: false

конфиг / Инициализаторы / omniauth.rb

OmniAuth.config.logger = Rails.logger
SERVICES = YAML.load(File.open("#{::Rails.root}/config/oauth.yml").read)
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :facebook, SERVICES['facebook']['key'], SERVICES['facebook']['secret'], iframe:   true
end

application_controller.rb

before_filter :add_xframe
def add_xframe
  headers['X-Frame-Options'] = 'GOFORIT'
end

Вам нужен контроллер для вызова из настроек холста Facebook, я использовал /canvas/и сделал маршрут основным SiteControllerдля этого приложения:


class SiteController < ApplicationController
  def index
    @user = User.new
  end
  def canvas
    redirect_to '/auth/failure' if request.params['error'] == 'access_denied'
    url = params['code'] ? "/auth/facebook?signed_request=#{params['signed_request']}&state=canvas" : "/login"
    redirect_to url
  end
  def login
  end
end

login.html.erb


<% content_for :javascript do %>
  var oauth_url = 'https://www.facebook.com/dialog/oauth/';
  oauth_url += '?client_id=471466299609256';
  oauth_url += '&redirect_uri=' + encodeURIComponent('https://apps.facebook.com/wellbeingtracker/');
  oauth_url += '&scope=email,status_update,publish_stream';
console.log(oauth_url);
  top.location.href = oauth_url;
<% end %>

источники

  • Я думаю, что конфиг взят из примера omniauth.
  • Файл gem (который является ключевым !!!) взят из: slideshare вещей, которые я узнал ...
  • Этот вопрос стека имел весь угол Xframe, так что вы получите пустое место, если вы не поместите этот заголовок в контроллер приложения.
  • И мой человек @rafmagana написал это руководство по герою , которое теперь вы можете принять за рельсы с этим ответом и за плечи великанов, с которыми вы ходите.

2

TARGET = "_ родителя

Используя идею Кевина Веллы, я попытался добавить этот атрибут к элементам формы, созданным генератором кнопок PayPal. У меня получилось так, что Paypal не открывается в новом окне / вкладке браузера.


К сожалению, это не работает для сафари тоже.
Wtower

1

Я не уверен, насколько это актуально, но я нашел обходной путь к этому. На моем сайте я хотел отобразить ссылку в модальном окне, содержащем iframe, который загружает URL.

То, что я сделал, я связал событие click ссылки с этой функцией javascript. Все это делает запрос к файлу PHP, который проверяет заголовки URL для X-FRAME-Options, прежде чем решить, загружать ли URL в модальном окне или перенаправлять.

Вот функция:

  function opentheater(link, title){
        $.get( "url_origin_helper.php?url="+encodeURIComponent(link), function( data ) {
  if(data == "ya"){
      $(".modal-title").html("<h3 style='color:480060;'>"+title+"&nbsp;&nbsp;&nbsp;<small>"+link+"</small></h3>");
        $("#linkcontent").attr("src", link);
        $("#myModal").modal("show");
  }
  else{
      window.location.href = link;
      //alert(data);
  }
});


        }

Вот код файла PHP, который проверяет это:

<?php
$url = rawurldecode($_REQUEST['url']);
$header = get_headers($url, 1);
if(array_key_exists("X-Frame-Options", $header)){
    echo "nein";
}
else{
    echo "ya";
}


?>

Надеюсь это поможет.


1

Я столкнулся с этой проблемой при запуске веб-сайта WordPress. Я пробовал все виды вещей, чтобы исправить это, и не был уверен, как, в конечном счете, проблема заключалась в том, что я использовал переадресацию DNS с маскированием, а ссылки на внешние сайты не обрабатывались должным образом. т. е. мой сайт был размещен по адресу http: //123.456.789/index.html, но был замаскирован для работы по адресу http://somewebSite.com/index.html . Когда я вошел http: //123.456.789/index.html в браузере, щелкнув по этим же ссылкам, я не обнаружил проблем с X-frame- в консоли JS, но запустил http://somewebSite.com/index.html.сделал. Чтобы правильно замаскировать, вы должны добавить DNS-серверы вашего хоста в службу вашего домена, т.е. у godaddy.com должны быть серверы имен, например, ns1.digitalocean.com, ns2.digitalocean.com, ns3.digitalocean.com, если вы были используя digitalocean.com в качестве хостинга.


1
Я закончил тем, что делал: remove_action( 'admin_init', 'send_frame_options_header',10);чтобы обойти эту проблему ...
Маджик

1

Удивительно, что никто здесь никогда не упоминал Apacheнастройки сервера ( *.confфайлы) или .htaccessсам файл как причину этой ошибки. Выполните поиск по файлам .htaccessили Apacheфайлам конфигурации, убедившись, что для вас не установлено следующее значение DENY:

Header always set X-Frame-Options DENY

Изменяя его SAMEORIGIN, заставляет вещи работать как положено:

Header always set X-Frame-Options SAMEORIGIN


это было упомянуто ранее - см. комментарий @Jay к ответу stackoverflow.com/a/6767901/1875965
Сандра

Я настраиваю .conf файл Заголовок всегда устанавливаю X-Frame-Options SAMEORIGIN!
GeekHades

Но как это относится к вопросу здесь, где заголовок приходит с внешних серверов, прямо к клиенту , IOW, ваш собственный сервер даже не задействован? Я что-то пропустил?
СЗ

1

Единственный реальный ответ, если вы не контролируете заголовки вашего источника, который вы хотите в своем iframe, - это прокси. Пусть сервер выступит в роли клиента, получит источник, удалит проблемные заголовки, добавит CORS, если необходимо, и затем пингует ваш собственный сервер.

Есть еще один ответ, объясняющий, как написать такой прокси. Это не сложно, но я был уверен, что кто-то должен был сделать это раньше. По какой-то причине это было просто трудно найти.

Я наконец нашел некоторые источники:

https://github.com/Rob--W/cors-anywhere/#documentation

^ предпочтительнее. Если вам нужно редкое использование, я думаю, вы можете просто использовать его приложение heroku. В противном случае, это код для запуска самостоятельно на вашем собственном сервере. Обратите внимание, каковы пределы.

whateverorigin.org

^ Второй выбор, но довольно старый. предположительно более новый выбор в python: https://github.com/Eiledon/alloworigin

тогда есть третий выбор:

http://anyorigin.com/

Который, кажется, допускает небольшое бесплатное использование, но помещает вас в публичный список позора, если вы не платите и используете какую-то неуказанную сумму, с которой вы можете быть удалены, только если вы заплатите комиссию ...


0

Не упоминается, но может помочь в некоторых случаях:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState !== 4) return;
    if (xhr.status === 200) {
        var doc = iframe.contentWindow.document;
        doc.open();
        doc.write(xhr.responseText);
        doc.close();
    }
}
xhr.open('GET', url, true);
xhr.send(null);

0

Используйте эту строку, приведенную ниже, вместо header()функции.

echo "<script>window.top.location = 'https://apps.facebook.com/yourappnamespace/';</script>";

0

у меня была эта проблема, и я решил ее, отредактировав httd.conf

<IfModule headers_module>
    <IfVersion >= 2.4.7 >
        Header always setifempty X-Frame-Options GOFORIT
    </IfVersion>
    <IfVersion < 2.4.7 >
        Header always merge X-Frame-Options GOFORIT
    </IfVersion>
</IfModule>

я поменял SAMEORIGIN на GOFORIT и перезапустил сервер


-1

Попробуйте это, я не думаю, что кто-то предлагал это в теме, это решит как 70% вашей проблемы, для некоторых других страниц вам придется отказаться, у меня есть полное решение, но не для общественности,

ДОБАВИТЬ ниже в свой iframe

sandbox = "allow-same-origin-allow-scripts allow-popups allow-формы"


1
песочница уменьшает привилегии, но не добавляет их. см. html5rocks.com/en/tutorials/security/sandboxed-iframes
Кайл Бейкер,

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.