Odmowa wyświetlania w ramce, ponieważ ustawiono opcję „X-Frame-Options” na „SAMEORIGIN”


272

Tworzę stronę internetową, która ma reagować, aby ludzie mieli do niej dostęp z poziomu swoich telefonów. Witryna ma zabezpieczone części, do których można się zalogować za pomocą Google, Facebook, ... itd. (OAuth).

Backend serwera jest rozwijany przy użyciu ASP.Net Web API 2, a frontend to głównie AngularJS z niektórymi Razorami.

W przypadku części uwierzytelniającej wszystko działa poprawnie we wszystkich przeglądarkach, w tym na Androidzie, ale uwierzytelnianie Google nie działa na iPhonie i wyświetla mi ten komunikat o błędzie

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

Jeśli o mnie chodzi, nie używam ramek iframe w swoich plikach HTML.

Przeszukiwałem Google, ale żadna odpowiedź nie dała mi rozwiązania problemu.


Ramki iframe są czasami używane przez usługi, z którymi się łączysz, nawet jeśli nie są widoczne (na pierwszy rzut oka)
NoWomenNoCry

Odpowiedzi:


171

Znalazłem lepsze rozwiązanie, może to pomoże ktoś zastąpić "watch?v="przez "v/"i będzie działać

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

51
Możesz także zmienić tę opcję, aby używać „embed /” zamiast „v /”, aby pełny adres URL wyglądałby następująco:<iframe width='1080' height='760' src="https://www.youtube.com/embed/dQw4w9WgXcQ" frameborder="0" allowfullscreen></iframe>
wstecz

1
proponuję zmienić tę odpowiedź na „embed /”, ponieważ „v /” już nie działa
tm81

88

OK po spędzeniu na tym więcej czasu przy pomocy tego postu SO

Przezwyciężanie „Wyświetlanie zabronione przez X-Frame-Opcje”

Udało mi się rozwiązać problem, dodając &output=embedna końcu adresu URL przed opublikowaniem na URL Google:

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

1
tak naprawdę jest to dla OAUTH, jak powiedziałem w moim oryginalnym poście. i nadal działa w OAUTH 2.0. chociaż Google zmieniło ustawienia, aby korzystać z usługi, więc teraz będziesz musiał specjalnie zmienić niektóre właściwości, aby korzystać z OAUTH 2.0 i tak jest w przypadku oprogramowania pośredniego OWIN 3.0. Odnoś się do tego linku, jeśli pojawia się komunikat o błędzie „odmowa dostępu”. blogs.msdn.com/b/webdev/archive/2014/07/02/…
Ali Hmer

1
@AliHmer Wielkie dzięki, kolego. Uratowałeś mi dzień :) & output = embed działało jak urok dla mnie .. :)
Sahil Manchanda

1
Nie działa również w ramkach iframe kalendarza Google w widoku aplikacji.
NoBugs


35

W tym przypadku ustawili nagłówek na SAMEORIGIN, co oznacza, że ​​zabronili ładowania zasobu w ramce iframe poza swoją domeną. Dlatego ten element iframe nie może wyświetlać się w wielu domenach

wprowadź opis zdjęcia tutaj

W tym celu musisz dopasować lokalizację w apache lub innej usłudze, z której korzystasz

Jeśli używasz apache, to w pliku 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>

2
Co to jest your_relative_path?
Zielony

2
Co to jest twoja_relatywna_ścieżka?
Sobiaholic


11

Aby osadzić wideo z YouTube na stronie angularjs, możesz po prostu użyć następującego filtru do swojego filmu

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

Wprowadziłem poniższe zmiany i działa dobrze dla mnie.

Po prostu dodaj atrybut <iframe src="URL" target="_parent" />

_parent: otworzy to osadzoną stronę w tym samym oknie.

_blank: W innej zakładce


1
Nie wiem, jak istotna jest ta odpowiedź na pierwotne pytanie, ale w moim przypadku, w innym kontekście, dostarczyła rozwiązania
Éric Viala

4

Dla mnie poprawka polegała na wejściu na console.developer.google.com i dodaniu domeny aplikacji do sekcji „Początki Javascript” poświadczeń OAuth 2.


2

Trochę późno, ale ten błąd może być również spowodowany, jeśli użyjesz native application Client IDzamiast web application Client ID.


Co masz na myśli? Zauważyłem również, że ramka działa w oknie Safari, ale nie w ramce iframe aplikacji, ale jak to zmienić?
NoBugs

Mój problem był podobny: podczas tworzenia identyfikatora klienta aplikacji internetowej nie
podałem adresu URL

2

Miałem ten sam problem z implementacją w Angular 9. Oto dwa kroki, które zrobiłem:

  1. Zmień adres URL YouTube z https://youtube.com/your_codena https://youtube.com/embed/your_code.

  2. A następnie przekaż adres URL DomSanitizerAngulara.

    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>

1

Jest dla mnie rozwiązanie, które odnosi się do rodzica. Po uzyskaniu adresu URL przekierowującego na stronę uwierzytelniania Google możesz wypróbować następujący kod:

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

0

Dzięki za pytanie. W przypadku iframe YouTube pierwszym problemem jest podany adres URL, czyli osadzony adres URL lub link URL z paska adresu. ten błąd w przypadku niezamieszczonego adresu URL, ale jeśli chcesz podać niezamieszczony adres URL, musisz zakodować w „bezpiecznej potoku”, np. (zarówno dla niezamieszczonego, jak i osadzonego adresu 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);
        }

     }

   }
}

rozdzieli „vedioId”. Musisz uzyskać identyfikator wideo, a następnie ustawić adres URL jako osadzony. W formacie HTML

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

Angular 2/5 dzięki jeszcze raz.


0

dodaj poniżej z sufiksem URL

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

0

Miałem podobny problem z osadzaniem czatu na youtube i ja to rozgryzłem. Być może istnieje podobne rozwiązanie dla podobnego problemu.

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'

Moja strona działa z www i bez niego. Aby więc działało, musisz upewnić się, że załadowałeś ten, który jest wymieniony na wartości embed_domain = ... Może brakuje Ci zmiennej, która powie, gdzie osadzić iframe. Aby rozwiązać mój problem, musiałem napisać skrypt wykrywający właściwą stronę internetową i wykonać prawidłową nazwę domeny osadzonej w ramce iframe.

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

lub

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

Zrozum, że nie używasz ramek iframe, ale nadal może istnieć jakaś zmienna, którą musisz dodać do swojej składni, aby powiedzieć jej, gdzie skrypt będzie używany.


-1

Wystąpił podobny problem podczas korzystania z iframe do wylogowania podstron z różnymi domenami. Rozwiązaniem, które zastosowałem było załadowanie ramki iframe, a następnie zaktualizowanie źródła po załadowaniu ramki.

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);
});


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.