拒绝在框架中显示,因为它将 'X-Frame-Options' 设置为 'SAMEORIGIN'。

359
我正在开发一个网站,应该是响应式的,这样人们可以从手机上访问它。该网站有一些安全部分,可以使用Google、Facebook等登录(OAuth)。
服务器后端使用ASP.NET Web API 2开发,前端主要是AngularJS和一些Razor。
对于认证部分,在所有浏览器中,包括Android,一切都正常工作,但是在iPhone上Google认证不起作用,并且给我显示了这个错误消息:
Refused to display 'https://accounts.google.com/o/openid2/auth
?openid.ns=http://specs.openid.ne…tp://axschema.org/namePerson
/last&openid.ax.required=email,name,first,last'
in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.

就我个人而言,我在我的HTML文件中没有使用任何iframe。
我在网上搜索了一下,但没有找到解决这个问题的答案。

即使在第一眼看不到的情况下,有些你连接到的服务仍然会使用iframes。 - NoWomenNoCry
20个回答

176
我找到了一个更好的解决方案。将"watch?v="替换为"v/",它就会起作用。
var url = url.replace("watch?v=", "v/");

60
你可以将使用 "v/" 替换为 "embed/",这样完整的 URL 就会变成:<iframe width='1080' height='760' src="https://www.youtube.com/embed/dQw4w9WgXcQ" frameborder="0" allowfullscreen></iframe> - backwardm
5
我建议将这个答案更改为 "embed/",因为 "v/" 不再起作用。 - tm81

113
好的,在花了更多时间并在 Stack Overflow 的帖子“克服“X-Frame-Options”禁止显示”的帮助下,我成功地解决了这个问题,通过在发布到 Google URL 之前在 URL 的末尾添加 &output=embed
var url = data.url + "&output=embed";
window.location.replace(url);

2
实际上,这是关于OAUTH的,就像我在原帖中所说的那样,并且在OAUTH 2.0中仍然如此。尽管如此,Google已经更改了其设置以使用该服务,因此现在您需要特别更改一些属性才能使用OAUTH 2.0,这也是OWIN 3.0中间件的情况。如果您收到“access_denied”错误消息,请参考此链接。http://blogs.msdn.com/b/webdev/archive/2014/07/02/changes-to-google-oauth-2-0-and-updates-in-google-middleware-for-3-0-0-rc-release.aspx - Ali Hmer
3
@AliHmer,非常感谢你啊伙计。你救了我的一天 :) &output=embed 对我来说效果非常好.. :) - Sahil Manchanda
2
在应用程序的Web视图中,Google日历iframe也无法正常工作。 - NoBugs
2
如果我想在移动应用程序中使用iframe显示我的其他网站,我该如何做? - user9542422
1
@AliHmer 当我使用&output=embed时,出现了一个错误,错误信息是检测到一个潜在危险的请求路径值。你能给我一个解决这个问题的建议/解决方案吗? - Balagurunathan Marimuthu
值得一提的是,&output=embed 是(或曾经是)谷歌特有的解决方法。也就是说,谷歌会看到 &output=embed 并删除 x-frame-options: SAMEORIGIN 响应头,但如果您试图嵌入不遵循相同约定的 www.apple.com(而且他们这样做是有充分理由的),那么这并不能帮助您。也就是说,这不是一个适用于所有情况的解决方案 - ruffin

53

在这种情况下,他们将标头设置为SAMEORIGIN,这意味着他们已经禁止在其域之外的iframe中加载资源。因此,该iframe无法显示跨域内容。

输入图像描述

为此,您需要匹配您正在使用的apache或任何其他服务中的位置。

如果您正在使用apache,则在httpd.conf文件中进行设置。

  <LocationMatch "/your_relative_path">
      ProxyPass absolute_path_of_your_application/your_relative_path
      ProxyPassReverse absolute_path_of_your_application/your_relative_path
   </LocationMatch>

8
your_relative_path是什么? - Green
8
你的相对路径是什么? - Sobiaholic
我认为这解释了为什么你不能清晰地嵌入第三方网站,但如果我正确理解了你的建议,它假定你可以匹配你要嵌入的网站的来源。是这样吗?也就是说,如果我想嵌入 www.apple.com,而他们在请求时发送了 x-frame-options: SAMEORIGIN,那我就没戏了。 - ruffin

45
尝试使用 https://www.youtube.com/embed/YOUR_VIDEO_CODE
您可以在“嵌入代码”部分找到所有嵌入代码,它看起来像这样:
<iframe width="560" height="315"  src="https://www.youtube.com/embed/YOUR_VIDEO_CODE" frameborder="0" allowfullscreen></iframe>

嵌入式:你是指“嵌入式”吗? - undefined

20
如果你在使用iframe来嵌入Vimeo,请将URL更改为:

https://vimeo.com/63534746

给:

http://player.vimeo.com/video/63534746

对我来说有效。

如果有人快速浏览并使用此解决方案,请注意从HTTPS更改为HTTP,这是一种不安全的协议。您的要求可能会有所不同,但请谨慎选择。个人建议避免使用此解决方案。另外,HTTP很快就会过时,我不会感到惊讶,如果在不久的将来浏览器完全不允许使用它。 - LosManos
这对我有效 - 我实际上使用了https: - moodyjive

10
要将YouTube视频嵌入到您的AngularJS页面中,您可以简单地使用以下过滤器来处理您的视频:
app.filter('scrurl', function($sce) {
    return function(text) {
        text = text.replace("watch?v=", "embed/");
        return $sce.trustAsResourceUrl(text);
    };
});

<iframe class="ytplayer" type="text/html" width="100%" height="360" src="{{youtube_url | scrurl}}" frameborder="0"></iframe>

8
我做了以下更改,对我来说效果很好。
只需添加属性 <iframe src="URL" target="_parent" />_parent:这将在同一窗口中打开嵌入的页面。 _blank:在不同的选项卡中打开。

1
我不知道那个回答与原问题有多大的相关性,但在我的情况下,在另一个上下文中,它提供了解决方案。 - Éric Viala

7
对我来说,解决方法是在console.developer.google.com中添加应用程序域到OAuth 2凭据的“Javascript Origins”部分。

4

我在实施Angular 9时遇到了同样的问题。 我完成了以下两个步骤:

  1. Change your YouTube URL from https://youtube.com/your_code to https://youtube.com/embed/your_code.

  2. And then pass the URL through DomSanitizer of Angular.

    import { Component, OnInit } from "@angular/core";
    import { DomSanitizer } from '@angular/platform-browser';
    
    @Component({
      selector: "app-help",
      templateUrl: "./help.component.html",
      styleUrls: ["./help.component.scss"],
    })
    export class HelpComponent implements OnInit {
    
      youtubeVideoLink: any = 'https://youtube.com/embed/your_code'
    
      constructor(public sanitizer: DomSanitizer) {
        this.sanitizer = sanitizer;   
      }
    
      ngOnInit(): void {}
    
      getLink(){
        return this.sanitizer.bypassSecurityTrustResourceUrl(this.youtubeVideoLink);
      }
    
    }
    
    <iframe width="420" height="315" [src]="getLink()" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
    

2

我有一个解决方案,适用于与父级相关的情况。在获取将重定向到Google身份验证页面的URL后,您可以尝试以下代码:

var loc = redirect_location;      
window.parent.location.replace(loc);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接