306
votes

I am developing a website that is supposed to be responsive so that people can access it from their phones. The site has got some secured parts that can be logged into using Google, Facebook, ...etc (OAuth).

The server backend is developed using ASP.Net Web API 2 and the front end is mainly AngularJS with some Razor.

For the authentication part, everything is working fine in all browsers including Android but the Google authentication is not working on iPhone and it gives me this error message

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'.

Now as far I am concerned I do not use any iframe in my HTML files.

I googled around, but no answer got me to fix the issue.

17
iframes are sometimes being used by services you connect to even if it is not visible (at first sight)NoWomenNoCry

17 Answers

177
votes

I found a better solution, maybe it can help somebody replace "watch?v=" by "v/" and it will work

var url = url.replace("watch?v=", "v/");
97
votes

O.K. after spending more time on this with the help of this SO post

Overcoming "Display forbidden by X-Frame-Options"

I managed to solve the issue by adding &output=embed to the end of the url before posting to the google URL:

var url = data.url + "&output=embed";
window.location.replace(url);
46
votes

Try to use

https://www.youtube.com/embed/YOUR_VIDEO_CODE

You can find all embeded code in 'Embeded Code' section and that looks like this

<iframe width="560" height="315"  src="https://www.youtube.com/embed/YOUR_VIDEO_CODE" frameborder="0" allowfullscreen></iframe>
42
votes

They have set the header to SAMEORIGIN in this case, which means that they have disallowed loading of the resource in an iframe outside of their domain. So this iframe is not able to display cross domain

enter image description here

For this purpose you need to match the location in your apache or any other service you are using

If you are using apache then in httpd.conf file.

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

If you are using iframe for vimeo, change the url from:

https://vimeo.com/63534746

to:

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

It works for me.

12
votes

For embeding youtube video into your angularjs page, you can simply use following filter for your video

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>
7
votes

I did the below changes and works fine for me.

Just add the attribute <iframe src="URL" target="_parent" />

_parent: this would open embedded page in same window.

_blank: In different tab

4
votes

For me the fix was to go into console.developer.google.com and add the application domain to "Javascript Origins" section of OAuth 2 credentials.

4
votes

I was having the same issue implementing in Angular 9. These are the two steps I did:

  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
votes

Little late, but this error can also be caused if you use a native application Client ID instead of a web application Client ID.

1
votes

There is a solution that worked for me, referring to the parent. After getting the url that will redirect to google authentication page, you can try the following code:

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

Thanks for the question. For YouTube iframe the first issue is the URL you have given, is it embedded URL or URL link from address bar. this error for non embed URL but if you want to give non embed URL then you need to code in "safe Pipe" like(for both non embedded or embed URL ) :

import {Pipe, PipeTransform} from '@angular/core';
import {DomSanitizer} from '@angular/platform-browser';

@Pipe({name: 'safe'})
export class SafePipe implements PipeTransform {

constructor(private sanitizer: DomSanitizer) {

}

transform(value: any, url: any): any {
    if (value && !url) {
        const regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
        let match = value.match(regExp);
        if (match && match[2].length == 11) {
            console.log(match[2]);
            let sepratedID = match[2];
            let embedUrl = '//www.youtube.com/embed/' + sepratedID;
            return this.sanitizer.bypassSecurityTrustResourceUrl(embedUrl);
        }

     }

   }
}

it will split out "vedioId". You have to get video id then set to URL as embedded. In Html

 <div>
   <iframe width="100%" height="300" [src]="video.url | safe"></iframe>
 </div>

Angular 2/5 thanks again.

0
votes

add the below with URL Suffix

/override-http-headers-default-settings-x-frame-options
0
votes

Had an similar issue embeding youtube chat and I figure it out. Maybe there is a similar solution for similar problem.

Refused to display 'https://www.youtube.com/live_chat?v=yDc9BonIXXI&embed_domain=your.domain.web' in a frame because it set 'X-Frame-Options' to 'sameorigin'

My webpage works with www and without it. So to make it work you need to make sure you load the one that is listed on the embed_domain= value... Maybe there is a variable your missing to tell where to embed your iframe. To fix my problem had to write a script to detect the right webpage and execute proper iframe embed domain name.

<iframe src='https://www.youtube.com/live_chat?v=yDc9BonIXXI&embed_domain=your.domain.web' width="100%" height="600" frameborder='no' scrolling='no'></iframe>

or

<iframe src='https://www.youtube.com/live_chat?v=yDc9BonIXXI&embed_domain=www.your.domain.web' width="100%" height="600" frameborder='no' scrolling='no'></iframe>

Understand you are not using iframes, but still there may be some variable you need to add to your syntax to tell it where the script is going to be used.

0
votes

On apache you need to edit security.conf:

nano /etc/apache2/conf-enabled/security.conf

and set:

Header set X-Frame-Options: "sameorigin"

Then enable mod_headers:

cd /etc/apache2/mods-enabled

ln -s ../mods-available/headers.load headers.load

And restart Apache:

service apache2 restart

And voila!

-1
votes

Ran into this similar issue while using iframe to logout of sub sites with different domains. The solution I used was to load the iframe first, then update the source after the frame is loaded.

var frame = document.createElement('iframe');
frame.style.display = 'none';
frame.setAttribute('src', 'about:blank');
document.body.appendChild(frame);
frame.addEventListener('load', () => {
  frame.setAttribute('src', url);
});