克服“ X框架选项禁止的显示”


419

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

是否有任何其他成帧或非成帧方法可以在单个窗口中显示不会被X-Frame-Options标头绊倒的页面?


117
如果它们是您的页面,请移除框架限制器。否则,请尊重页面作者的意愿,并且不要构架它们。
Marc B

如果您在使用Facebook App并使用AJAX调用时遇到此错误,我读到了Facebook真正喜欢使用#标签作为ajax联系人的地方,因此尝试更改链接对我有用。
eric.itzhak

28
@MarcB Chrome和Firefox在本机UI镶边中以道德的方式构架了非所有网站。这些程序还允许其所有者FWIW放宽同源政策。正如garen-checkly所说:“我正在写一个很小的网页,其目的是构架其他几页,只是将它们合并到一个浏览器窗口中,以便于查看。” 这基本上是在扩展网络浏览器,并且完全合乎道德。声明的意图与编写bash脚本以打开和排列浏览器窗口没有什么不同。
塞缪尔·丹尼尔森

1
检查Surfly。它可以完全满足您的需求。
muodov

1
@MarcB没有帮助。OP可能不在乎页面作者的意愿。
flarn2006 '19

Answers:


211

我遇到了类似的问题,我试图在iframe中显示我们自己网站的内容(作为带有Colorbox的灯箱样式对话框),并且在源服务器阻止它加载到我们的测试服务器上。

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

例如。对于PHP,

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

页面顶部的内容将使浏览器将两者结合起来,从而产生一个标头

X-Frame-Options SAMEORIGIN, GOFORIT

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

祝一切顺利!


3
我在网站周围有一个框架。在我的网站上,我将重定向到Instagram以获取OAUTH。由于Instagram发送X-Frame-Options: SAMEORIGIN,因此无法在框架内执行此操作。您必须使用一个弹出窗口。
史蒂夫·陶伯

16
使用PHP,最好在可以使用新header_remove功能的情况下使用新功能(> = 5.3.0)。
一只猫,

11
或者,如果您想从整个目录中删除X-Frame-Options,则可以编辑.htaccess。只需添加以下行:Header always unset X-Frame-Options
Jay

4
@cawecoy:是的,整个问题在于它是无效的。它依赖于浏览器忽略无效的标头和“失败打开”,这是未指定的行为,相当依赖。GOFORIT(或其他随机的任意无效令牌)故意破坏服务器应用的安全措施;如果您自己控制服务器(对于任何真正的公共服务都应该这样做),那么正确的做法就是将服务器设置为不首先设置标头。
bobince 2013年

31
这似乎在Chrome中不再起作用。无效的值导致该值默认为DENY。
jamesfm 2014年

159

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

您也可以替换watch?v=embed/这样http://www.youtube.com/watch?v=eCfDxZxTBW4http://www.youtube.com/embed/eCfDxZxTBW4


14
哦,进展...我希望他们将我们重定向到嵌入页面,而不是引发错误,并让我重写脚本!
joeytwiddle 2012年

122

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


120
这仅适用于将Google地图嵌入iframe中,而不适用于一般的“解决方案”。
本杰明·沃尔文德2011年

17
我需要在灯箱中嵌入Google地图,因此此“解决方案”非常完美
yitwail 2011年

5
如果您尝试使用Twitter网络意图进行此操作,请忽略它。整天都在尝试使用不同的灯箱插件而迷失了方向,只是发现“尽管可以在IFRAME和小部件中提供指向意图的链接,但无法将结果页面加载到IFRAME中。” 资料来源:Twitter网站。
古巴创(Gubatron)2012年

6
这样做,如果你想,即使你添加页面加载后剩下来加载IFRAME SRC不工作&output=embed
探路者

1
@pathfinder当页面加载后无法加载iframe src时,这对我有用
David Sykes 2014年

61

UPDATE 2019:可以绕过X-Frame-Options<iframe>仅使用客户端的JavaScript和我的X框,旁路 Web组件。这是一个演示:中的Hacker NewsX-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中适用于我,我可以在iframe中看到Hacker News。
niutech '16

1
@niutech会在Chrome 64中重新加载页面后起作用,但我第一次加载该页面时却无法正常工作。(以隐身方式尝试。)
卡尔·沃尔什

1
谢谢,太棒了!
安德鲁·甘斯

23

添加一个

  target='_top'

到我在facebook选项卡中的链接为我解决了这个问题...


1
对于另一个iframe中包含的Paypal iframe,我也有同样的问题。现在可以使用!谢谢
Fabrizio Fortino 2012年

4
我还添加了target ='_ top',但此解决方案的问题是,该链接现在在iframe外部的新标签页中打开,而没有Facebook画布。
sumitkanoje 2013年




7

这是解决方案的家伙!

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

唯一适用于Facebook应用程序的东西!



6

即使将x-frame选项设置为在外部网站上拒绝,也可以将外部网站加载到iFrame的解决方案。

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

srciFrame 的属性可以具有如下所示的网址:/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请求,可能已经是普通浏览器页面访问了。

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


几周前我就这样做了,在使用echo时,外部页面中使用的任何相对URL均不起作用。(通常是CSS和/或JS,因此除非在回显之前修改URL,否则您可能无法获得全部功能。)除非我错过了某些事情,...,
Ultrageek

不知道为什么会发生这种情况...它应该像普通的HTTP请求一样工作,就像最终用户在访问URL时执行的一样。因此,get_file_contents()的结果应该是一个完全正常的HTML页面。
弗洛里斯

5

我几乎尝试了所有建议。但是,真正解决问题的唯一方法是:

  1. .htaccess在您的PHP文件所在的文件夹中创建一个。

  2. 将此行添加到htaccess中:

    Header always unset X-Frame-Options

之后,应使用来自其他域的iframe嵌入PHP。

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

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

但是,对于我而言,这不是必需的。


标头始终未设置htaccess中的X-Frame-Options帮了我
大忙

4

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

我写解决了

$wgEditPageFrameOptions = "SAMEORIGIN"; 

进入mediawiki php配置文件。

希望能帮助到你。


3

FWIW:

iFrame当出现这种“破坏者”代码时,我们不得不杀死我们的情况。因此,我使用PHP function get_headers($url);在将远程URL显示为之前签出了远程URL iFrame。为了获得更好的性能,我将结果缓存到一个文件中,因此没有每次都进行HTTP连接。


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访问资源。

2

唯一有很多答案的问题。欢迎来到指南,我希望当我努力使其在截止日期的晚上10:30起作用时... FB使用画布应用程序做了一些奇怪的事情,而且,您已经被警告过。如果您仍然在这里并且您有一个Rails应用程序将出现在Facebook Canvas的后面,那么您将需要:

宝石文件:

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

config / facebook.yml

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

config / application.rb

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

config / initializers / 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文件(这是关键!!!)来自:幻灯片分享我学到的东西...
  • 该堆栈问题具有整个Xframe角度,因此,如果不将此标头放在应用程序控制器中,则会得到一个空格。
  • 我的人@rafmagana编写了这个heroku指南,现在您可以将这个答案以及与之同行的巨人的肩膀用于铁路。

2

target ='_ parent'

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


不幸的是,这似乎也不适合野生动物园。
Wtower

1

我不确定它的相关性,但是我为此建立了一个变通方法。在我的网站上,我想在模式窗口中显示链接,该窗口包含一个加载URL的iframe。

我所做的是,我将链接的click事件链接到了此javascript函数。所有这一切都是向PHP文件发出请求,该文件检查X-FRAME-Options的URL标题,然后再决定是将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时,单击那些相同的链接在JS控制台中没有出现X框架来源的问题,但是正在运行 http://somewebSite.com/index.html做到了。为了正确屏蔽,您必须将主机的DNS名称服务器添加到您的域服务中,例如,如果您是使用digitalocean.com作为您的托管服务。


1
我最终做了:remove_action( 'admin_init', 'send_frame_options_header',10);绕过这个问题...
majick

1

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

Header always set X-Frame-Options DENY

将其更改为SAMEORIGIN,可使一切正常运行:

Header always set X-Frame-Options SAMEORIGIN


之前提到过-请参阅@Jay对答案stackoverflow.com/a/6767901/1875965
Sandra

我配置.conf文件头总是设置X-Frame-Options SAMEORIGIN!
GeekHades

但这与这里的问题有何关系,在这里,标头来自外部服务器,直接到达客户端,甚至还没有涉及您自己的服务器的IOW?我想念什么吗?
Sz。

1

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

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

我终于找到了一些资料来源:

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

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

whatorigin.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,然后重新启动了服务器



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.