克服“X-Frame-Options禁止显示”

时间:2011-07-12 15:06:19

标签: iframe frames x-frame-options

我正在撰写一个小网页,其目的是构建其他几个页面,只需将它们合并到一个浏览器窗口中以便于查看。我试图框架的一些页面禁止被框架并抛出“拒绝显示文档,因为X-Frame-Options禁止显示”。 Chrome中的错误。我理解这是一个安全限制(有充分理由),并且无权更改它。

是否有任何替代框架或非框架方法在单个窗口中显示不会被X-Frame-Options标头绊倒的页面?

26 个答案:

答案 0 :(得分:208)

我有一个类似的问题,我试图在iframe中显示来自我们自己网站的内容(作为带有Colorbox的灯箱式对话框),我们在那里有一个服务器范围的“X-Frame” - 在源服务器上选择“SAMEORIGIN”标头,防止它在我们的测试服务器上加载。

这似乎没有在任何地方记录,但如果您可以编辑您尝试iframe的页面(例如,它们是您自己的页面),只需发送另一个带有任何字符串的X-Frame-Options标头完全禁用SAMEORIGIN或DENY命令。

例如。对于PHP,放

<?php
    header('X-Frame-Options: GOFORIT'); 
?>
页面顶部的

会使浏览器将两者合并,从而产生

标题
X-Frame-Options SAMEORIGIN, GOFORIT

...并允许您在iframe中加载页面。当初始SAMEORIGIN命令在服务器级别设置时,这似乎有效,并且您希望在逐页的情况下覆盖它。

一切顺利!

答案 1 :(得分:158)

如果您收到YouTube视频的此错误,而不是使用完整网址,请使用共享选项中的嵌入网址。它看起来像http://www.youtube.com/embed/eCfDxZxTBW4

您也可以将watch?v=替换为embed/,以便http://www.youtube.com/watch?v=eCfDxZxTBW4成为http://www.youtube.com/embed/eCfDxZxTBW4

答案 2 :(得分:122)

如果您在尝试在iframe中嵌入Google地图时收到此错误,则需要将&output=embed添加到源链接。

答案 3 :(得分:51)

更新2019年:您可以绕过X-Frame-Options仅使用客户端JavaScript和我的X-Frame-Bypass Web组件绕过<iframe> 。这是一个演示:Hacker News in an X-Frame-Bypass。 (在Chrome和Firefox中测试过。)

答案 4 :(得分:22)

添加

  target='_top'

到我在facebook标签中的链接为我解决了这个问题...

答案 5 :(得分:20)

Chrome有一个插件可以删除该标题条目(仅供个人使用):

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

答案 6 :(得分:19)

如果您在尝试嵌入Vimeo内容时收到此错误,请将iframe的src更改为:https://vimeo.com/63534746˙:http://player.vimeo.com/video/63534746 < / p>

答案 7 :(得分:13)

我在iframe中尝试嵌入moodle 2时遇到了同样的问题,解决方案是Site administration ► Security ► HTTP security并检查Allow frame embedding

答案 8 :(得分:7)

这是解决方案的人!!

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

Facebook应用程序唯一有用的东西!

答案 9 :(得分:5)

我几乎尝试了所有的建议。然而,唯一真正解决这个问题的是:

  1. 在PHP文件所在的同一文件夹中创建.htaccess

  2. 将此行添加到htaccess:

    Header always unset X-Frame-Options

  3. 通过iframe从其他域嵌入PHP应该可以使用。

    此外,您可以在PHP文件的开头添加:

    header('X-Frame-Options: ALLOW');
    
    然而,在我的情况下,这不是必需的。

答案 10 :(得分:5)

如果您使用 Content-Security-Policy <,则 X-Frame-Options Allow-From https:// ... 似乎已被折旧并被替换(并被忽略) / strong>标题代替。

以下是完整的参考:https://content-security-policy.com/

答案 11 :(得分:5)

将外部网站加载到iFrame中的解决方案即使在外部网站上设置为拒绝x框架选项也很难。

如果您想将其他网站加载到iFrame中并且您收到Display forbidden by X-Frame-Options”错误,那么您实际上可以通过创建服务器端代理脚本来克服此问题。

iFrame的src属性可能有这样的网址:/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请求,可能是一个普通的浏览器页面访问。

请注意:您可能希望提高此脚本的安全性。因为黑客可以通过代理脚本开始加载网页。

答案 12 :(得分:4)

我在mediawiki上遇到了同样的问题,这是因为出于安全原因,服务器拒绝将页面嵌入到iframe中。

我解决了写作

$wgEditPageFrameOptions = "SAMEORIGIN"; 

进入mediawiki php配置文件。

希望它有所帮助。

答案 13 :(得分:3)

FWIW:

我们遇到这种“断路器”代码出现时我们需要杀死iFrame的情况。因此,我使用PHP function get_headers($url);检查远程URL,然后在iFrame中显示它。为了获得更好的性能,我将结果缓存到文件中,因此每次都没有建立HTTP连接。

答案 14 :(得分:3)

我使用的是Tomcat 8.0.30,这些建议都没有对我有用。我们希望更新X-Frame-Options并将其设置为ALLOW,以下是我配置为允许嵌入iframe的方式:

  • 导航到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访问资源。

答案 15 :(得分:2)

<强>目标= '_父'

使用Kevin Vella的想法,我尝试将该属性添加到由PayPal的按钮生成器构成的元素中。为我工作,以便Paypal不会在新的浏览器窗口/标签页中打开。

答案 16 :(得分:2)

唯一有一堆答案的问题。我希望我能够在截止日当天晚上10点30分忙于工作时向我提供指导...... FB用画布应用做了一些奇怪的事情,好吧,你已经被警告了。如果你还在这里并且你有一个将出现在Facebook Canvas背后的Rails应用程序,那么你将需要:

<强>的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 things i learned...
  • 此堆栈问题具有整个Xframe角度,因此您将获得一个空格,如果 你没有把这个标题放在app控制器中。
  • 我的男人@rafmagana写了这个heroku guide,现在你可以采用这个答案的铁轨和你走路的巨人的肩膀。

答案 17 :(得分:1)

唯一真正的答案是,如果您不在iframe中控制源代码中的标题,则代理它。让服务器充当客户端,接收源,剥离有问题的标头,根据需要添加CORS,然后ping您自己的服务器。

另外还有一个答案解释了如何编写这样的代理。这并不困难,但我确信有人必须先做过这件事。由于某种原因,很难找到它。

我终于找到了一些消息来源:

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

^首选。如果您需要少量使用,我认为您可以使用他的heroku应用程序。否则,它是在您自己的服务器上自行运行的代码。请注意确定限制是什么。

whateverorigin.org

^第二选择,但相当老。据说是python的新选择:https://github.com/Eiledon/alloworigin

然后是第三种选择:

http://anyorigin.com/

这似乎允许一点点免费使用,但如果你不支付并使用一些未指明的金额,你会把你放在公共耻辱名单上,只有你支付费用才能将其删除......

答案 18 :(得分:1)

如果要从整个目录中删除X-Frame-Options,请编辑.htaccess。

并添加以下行:标头始终未设置X-Frame-Options

[内容来自:Overcoming "Display forbidden by X-Frame-Options"

答案 19 :(得分:1)

令人惊讶的是,此处没有人提到Apache服务器的设置(*.conf文件)或.htaccess文件本身是导致此错误的原因。搜索您的.htaccessApache配置文件,确保您未将以下内容设置为DENY

Header always set X-Frame-Options DENY

将其更改为SAMEORIGIN,可以按预期工作:

Header always set X-Frame-Options SAMEORIGIN

答案 20 :(得分:1)

我在运行wordpress网站时遇到过这个问题。我尝试了各种各样的东西来解决它,并且不确定如何,最终问题是因为我使用带掩码的DNS转发,并且没有正确处理外部站点的链接。即我的网站托管在http://123.456.789/index.html,但屏蔽了http://somewebSite.com/index.html。当我在浏览器中输入http://123.456.789/index.html时,单击相同的链接导致JS控制台中没有X-frame-origin问题,但运行http://somewebSite.com/index.html。为了正确掩盖,您必须将主机的DNS名称服务器添加到您的域服务,即godaddy.com应该具有示例的名称服务器,例如ns1.digitalocean.com,ns2.digitalocean.com,ns3.digitalocean.com,如果您是使用digitalocean.com作为您的托管服务。

答案 21 :(得分:1)

我不确定它有多相关,但我为此制定了一个解决方案。在我的网站上,我想在一个模态窗口中显示链接,该窗口包含一个加载URL的iframe。

我做的是,我将链接的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";
}


?>

希望这有帮助。

答案 22 :(得分: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 并重新启动服务器

答案 23 :(得分:0)

试试这个,我不认为有人在主题中建议这一点,这将解决你的问题的70%,对于其他一些页面,你必须废弃,我有完整的解决方案但不公开,

在下方添加到您的iframe

sandbox =“allow-same-origin allow-scripts allow-popups allow-forms”

答案 24 :(得分: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);

答案 25 :(得分:0)

使用下面给出的这一行而不是header()函数。

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