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


419

Piszę małą stronę internetową, której celem jest oprawienie kilku innych stron, po prostu konsolidacja ich w jednym oknie przeglądarki w celu ułatwienia przeglądania. Kilka stron, które próbuję wykadrować, zakazuje kadrowania i rzuca komunikat „Odmowa wyświetlenia dokumentu, ponieważ wyświetlanie jest zabronione przez Opcje X-Frame”. błąd w Chrome. Rozumiem, że jest to ograniczenie bezpieczeństwa (nie bez powodu) i nie mam dostępu, aby je zmienić.

Czy istnieje jakaś alternatywna metoda kadrowania lub nie-kadrowania, aby wyświetlić strony w jednym oknie, które nie zostaną uruchomione przez nagłówek Opcje X-Frame?


117
Jeśli to Twoje strony, usuń ogranicznik ramki. W przeciwnym razie uszanuj życzenia autora strony i NIE PONOWNIE JE ZDJĘĆ.
Marc B

Jeśli otrzymujesz ten błąd dla aplikacji na Facebooku i używasz wywołań AJAX, przeczytałem gdzieś, że Facebook naprawdę lubi używać # tagów do kontaktu z ajaxem, więc spróbuj zmienić linki, działało dla mnie.
eric.itzhak

28
@MarcB Chrome i Firefox etycznie oprawiają niepowiązane strony w natywny interfejs użytkownika Chrome. Programy te umożliwiają także właścicielom, FWIW, złagodzenie zasad tego samego pochodzenia. Jak powiedział Garen-Checkly: „Piszę małą stronę internetową, której celem jest oprawienie kilku innych stron, po prostu skonsolidowanie ich w jednym oknie przeglądarki w celu ułatwienia przeglądania”. To w zasadzie rozszerzenie przeglądarki internetowej i byłoby całkowicie etyczne. Podana intencja nie różni się niczym od napisania skryptu bash do otwierania i rozmieszczania okien przeglądarki.
Samuel Danielson

1
Sprawdź Surfly . Może zrobić dokładnie to, czego potrzebujesz.
muodov

1
@MarcB To nie jest pomocne. OP może nie przejmować się życzeniami autora strony.
flarn2006

Odpowiedzi:


211

Miałem podobny problem, gdy próbowałem wyświetlić zawartość z naszej witryny w ramce iframe (jako okno dialogowe w stylu lightbox z Colorbox ) i gdzie na serwerze mieliśmy nagłówek „X-Frame-Options SAMEORIGIN” na serwer źródłowy uniemożliwiający załadowanie go na nasz serwer testowy.

Wydaje się, że nie jest to nigdzie udokumentowane, ale jeśli możesz edytować strony, które próbujesz iframe (np. To twoje własne strony), po prostu wysyłając kolejny nagłówek Opcje X-Frame z dowolnym łańcuchem, w ogóle wyłącza polecenia SAMEORIGIN lub DENY.

na przykład. dla PHP, wprowadzenie

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

u góry strony sprawi, że przeglądarki połączą oba te elementy, co spowoduje powstanie nagłówka

X-Frame-Options SAMEORIGIN, GOFORIT

... i pozwala załadować stronę w ramce iframe. Wydaje się, że działa to, gdy początkowa komenda SAMEORIGIN została ustawiona na poziomie serwera, a chcesz zastąpić ją w przypadku strona po stronie.

Wszystkiego najlepszego!


3
Miałem ramkę wokół strony internetowej. Na mojej stronie przekierowuję na Instagram dla OAUTH. Ponieważ Instagram wysyła, X-Frame-Options: SAMEORIGINnie można tego zrobić w ramce. Musisz użyć wyskakującego okienka.
Steve Tauber,

16
W PHP prawdopodobnie lepiej jest użyć nowej header_removefunkcji, pod warunkiem, że jest ona dostępna (> = 5.3.0).
kot

11
Możesz też edytować plik .htaccess, jeśli chcesz usunąć X-Frame-Options z całego katalogu. Wystarczy dodać wiersz:Header always unset X-Frame-Options
Jay

4
@cawecoy: Cóż, chodzi o to, że jest nieprawidłowy. Polega on na tym, że przeglądarki ignorują nieprawidłowy nagłówek i „otwierają się niepomyślnie”, co jest nieokreślonym zachowaniem i jest dość podejrzane. GOFORIT(lub inny losowy dowolny nieważny token) celowo łamie środek bezpieczeństwa zastosowany przez serwer; jeśli sam kontrolujesz serwer (co powinieneś zrobić dla każdej prawdziwej usługi publicznej), to poprawne ustawienie serwera to nie ustawianie nagłówka w pierwszej kolejności.
bobince

31
Wydaje się, że to już nie działa w Chrome. Nieprawidłowe wartości powodują, że domyślna wartość to ODRZUĆ.
jamesfm

159

Jeśli pojawia się ten błąd w przypadku filmu na YouTube, zamiast pełnego adresu URL, użyj adresu URL do umieszczenia na stronie w opcjach udostępniania. Będzie to wyglądaćhttp://www.youtube.com/embed/eCfDxZxTBW4

Możesz również zastąpić watch?v=przez embed/to http://www.youtube.com/watch?v=eCfDxZxTBW4staje sięhttp://www.youtube.com/embed/eCfDxZxTBW4


14
O, postęp ... Chciałbym, aby po prostu przekierowali nas na stronę do umieszczenia na stronie zamiast powodować błąd i zmuszać mnie do przepisywania skryptów!
joeytwiddle

122

Jeśli pojawia się ten błąd podczas próby osadzenia mapy Google w pliku iframe, musisz dodać &output=embedlink źródłowy.


120
Dotyczy to tylko osadzania map Google w ramce iframe, a nie ogólnego „rozwiązania”.
Benjamin Wohlwend

17
Musiałem osadzić mapę Google w lightboxie, więc to „rozwiązanie” było idealne
yitwail,

5
Jeśli próbujesz to zrobić z intencją sieci Twitter, zapomnij o tym. Właśnie straciłem cały dzień, próbując różnych wtyczek lightbox, aby dowiedzieć się tego „Chociaż możesz podać linki do zamiarów w ramach IFRAME i widżetów, powstałe strony nie mogą zostać załadowane do IFRAME”. Źródło: witryna Twitter.
Gubatron

6
To nie działa, jeśli próbujesz załadować ramkę iframe src po załadowaniu reszty strony, nawet jeśli dodasz&output=embed
pathfinder

1
@pathfinder To działało dla mnie, gdy miałem problemy z ładowaniem iframe src po załadowaniu strony
David Sykes

61

UPDATE 2019: Ty może bypass X-Frame-Optionsw <iframe>użyciu tylko po stronie klienta JavaScript i mój X-FRAME-Bypass Web Component. Oto demo: Wiadomości Hackera wX-Frame-Bypass . (Testowane w Chrome i Firefox.)


3
To interesujące obejście. Działa dobrze w FF / Chrome / Opera, ale nie działa w IE / Edge. Ktoś, kto wie coś, co będzie?
Collector

7
To już nie działa. Daje „odmówił wyświetlenia„ news.ycombinator.com ”w ramce, ponieważ ustawił„ X-Frame-Options ”na„ DENY ”. zgodnie z oczekiwaniami
g.pickardou,

2
@ g.pickardou Działa dla mnie w Google Chrome 46, widzę Wiadomości Hackera w ramce iframe.
niutech

1
@niutech to skrzypce działa po przeładowaniu strony w Chrome 64, ale po pierwszym załadowaniu strony nie działa. (Spróbuj incognito.)
Carl Walsh

1
Dzięki, to jest niesamowite!
Andrew Gans,

23

Dodawanie

  target='_top'

do mojego linku w zakładce Facebook naprawiłem problem ...


1
Miałem ten sam problem z elementem iframe Paypal zawartym w innym elemencie iframe. Teraz działa! Dzięki
Fabrizio Fortino,

4
Dodałem również target = '_ top', ale problem z tym rozwiązaniem polega na tym, że link otwiera się teraz poza ramką iframe w nowej karcie bez kanwy Facebooka.
sumitkanoje,



13

Miałem ten sam problem, gdy próbowałem osadzić moodle 2 w ramce iframe, rozwiązaniem jest Site administration ► Security ► HTTP securityi sprawdźAllow frame embedding


dobrze zrobione dla metody Moodle, ponieważ inne metody zawodzą / zostają nadpisane.
ericosg

7

To jest rozwiązanie chłopaki !!

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

Jedyne, co działało w przypadku aplikacji na Facebooku!



6

Rozwiązanie do wczytywania zewnętrznej strony internetowej do iFrame, nawet jeśli opcja X-Frame jest ustawiona na odmowę na zewnętrznej stronie internetowej.

Jeśli chcesz załadować inną stronę internetową do ramki iFrame i pojawi się Display forbidden by X-Frame-Options”błąd, możesz faktycznie temu zaradzić, tworząc skrypt serwera proxy po stronie serwera.

srcAtrybutem iFrame może mieć URL wygląda tak:/proxy.php?url=https://www.example.com/page&key=somekey

Wtedy proxy.php wyglądałby mniej więcej tak:

if (isValidRequest()) {
   echo file_get_contents($_GET['url']);
}

function isValidRequest() {
    return $_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['key']) && 
    $_GET['key'] === 'somekey';
}

Pomija to blok, ponieważ jest to po prostu żądanie GET, które równie dobrze może być zwykłą wizytą w przeglądarce.

Pamiętaj: możesz chcieć poprawić bezpieczeństwo w tym skrypcie. Ponieważ hakerzy mogą rozpocząć ładowanie na stronach internetowych za pomocą skryptu proxy.


Robiłem to kilka tygodni temu, a wszelkie względne adresy URL użyte na stronie zewnętrznej nie działają podczas korzystania z echa. (Zazwyczaj CSS i / lub JS, więc możesz nie uzyskać pełnej funkcjonalności, chyba że zmodyfikujesz adresy URL przed
powtórzeniem

Nie jestem pewien, dlaczego tak się dzieje dla Ciebie ... Powinno to działać jak zwykłe żądanie HTTP, tak jak użytkownik końcowy wykonałby podczas odwiedzania adresu URL. Tak więc wynikiem get_file_contents () powinna być całkowicie działająca strona HTML.
Floris

5

Próbowałem prawie wszystkich sugestii. Jednak jedyną rzeczą, która naprawdę rozwiązała problem, było:

  1. Utwórz .htaccessw tym samym folderze, w którym znajduje się plik PHP.

  2. Dodaj tę linię do htaccess:

    Header always unset X-Frame-Options

Osadzanie PHP przez iframe z innej domeny powinno potem działać.

Dodatkowo możesz dodać na początku swojego pliku PHP:

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

Co w moim przypadku nie było konieczne.


Nagłówek zawsze wyłączony X-Frame-Opcje w htaccess
załatwił sprawę

4

Miałem ten sam problem z mediawiki, ponieważ serwer odmówił osadzenia strony w ramce iframe ze względów bezpieczeństwa.

Rozwiązałem to pisząc

$wgEditPageFrameOptions = "SAMEORIGIN"; 

do pliku konfiguracyjnego php mediawiki.

Mam nadzieję, że to pomoże.


3

FWIW:

Mieliśmy sytuację, w której musieliśmy zabić naszą osobę, iFramegdy pojawił się ten kod „breaker”. Tak więc użyłem PHP, function get_headers($url);aby sprawdzić zdalny adres URL przed wyświetleniem go w pliku iFrame. Aby uzyskać lepszą wydajność, buforowałem wyniki do pliku, więc nie nawiązywałem połączenia HTTP za każdym razem.


3

Korzystałem z Tomcat 8.0.30, żadna z sugestii nie działała dla mnie. Gdy chcemy zaktualizować X-Frame-Optionsi ustawić go ALLOW, oto jak skonfigurowałem, aby umożliwić osadzanie ramek iframe:

  • Przejdź do katalogu conf Tomcat, edytuj plik web.xml
  • Dodaj poniższy filtr:
<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> 
  • Uruchom ponownie usługę Tomcat
  • Uzyskaj dostęp do zasobów za pomocą ramki iFrame.

2

Jedyne pytanie, które ma wiele odpowiedzi. Przyjdź do przewodnika, który chciałbym mieć, kiedy starałem się o to, aby zadziałało o 10:30 w nocy w ostatecznym terminie ... FB robi dziwne rzeczy z aplikacjami na płótnie, i cóż, zostałeś ostrzeżony. Jeśli nadal tu jesteś i masz aplikację Rails, która pojawi się za kanwą Facebooka, będziesz potrzebować:

Gemfile:

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

Potrzebujesz kontrolera, aby zadzwonić z ustawień kanwy Facebooka, użyłem /canvas/i ustawiłem trasę jako główną SiteControllerdla tej aplikacji:


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

Źródła

  • Myślę, że konfiguracja pochodzi z przykładu omniauth.
  • Plik klejnotów (który jest kluczem !!!) pochodzi z: pokazu slajdów, którego się nauczyłem ...
  • To pytanie stosu miało cały kąt Xframe, więc otrzymasz puste miejsce, jeśli nie umieścisz tego nagłówka w kontrolerze aplikacji.
  • A mój człowiek @rafmagana napisał ten przewodnik heroku , który teraz możesz adoptować do szyn z tą odpowiedzią i ramionami gigantów, z którymi idziesz.

2

target = „_ rodzic”

Korzystając z pomysłu Kevina Velli, próbowałem dodać ten atrybut do elementów tworzonych przez generator przycisków PayPal. Pracował dla mnie, aby Paypal nie otwierał się w nowym oknie / karcie przeglądarki.


Niestety nie wydaje się to również działać w przypadku safari.
Wtower

1

Nie jestem pewien, czy ma to znaczenie, ale opracowałem obejście tego problemu. Na mojej stronie chciałem wyświetlić link w oknie modalnym zawierającym element iframe, który ładuje adres URL.

Połączyłem zdarzenie click łącza z tą funkcją javascript. Wszystko to polega na wysłaniu żądania do pliku PHP, który sprawdza nagłówki URL dla X-FRAME-Options przed podjęciem decyzji, czy załadować adres URL w oknie modalnym, czy przekierować.

Oto funkcja:

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


        }

Oto kod pliku PHP, który go sprawdza:

<?php
$url = rawurldecode($_REQUEST['url']);
$header = get_headers($url, 1);
if(array_key_exists("X-Frame-Options", $header)){
    echo "nein";
}
else{
    echo "ya";
}


?>

Mam nadzieję że to pomoże.


1

Natknąłem się na ten problem podczas prowadzenia strony internetowej wordpress. Próbowałem różnych rzeczy, aby to naprawić i nie byłem pewien, jak to się stało, ostatecznie problem polegał na tym, że korzystałem z przekazywania DNS z maskowaniem, a linki do zewnętrznych stron nie były odpowiednio adresowane. tj. moja witryna była hostowana pod adresem http: //123.456.789/index.html, ale została zamaskowana do działania pod adresem http://somewebSite.com/index.html . Kiedy podałem http: //123.456.789/index.html w przeglądarce, kliknięcie tych samych łączy nie spowodowało problemów z początkiem ramki X w konsoli JS, ale uruchomiłem http://somewebSite.com/index.htmlzrobił. Aby poprawnie maskować, musisz dodać serwery nazw DNS swojego hosta do usługi domenowej, tj. Godaddy.com powinien mieć serwery nazw np. Ns1.digitalocean.com, ns2.digitalocean.com, ns3.digitalocean.com, jeśli byłeś używanie digitalocean.com jako usługi hostingowej.


1
Skończyło się to na: remove_action( 'admin_init', 'send_frame_options_header',10);ominięciu tego problemu ...
majick

1

Zaskakujące jest to, że nikt tutaj nie wspomniał Apacheo ustawieniach serwera ( *.confplikach) lub .htaccesso samym pliku jako o przyczynie tego błędu. Przeszukuj pliki konfiguracyjne .htaccesslub Apachepliki, upewniając się, że nie masz następujących ustawień DENY:

Header always set X-Frame-Options DENY

Zmiana na SAMEORIGINsprawia, że ​​wszystko działa zgodnie z oczekiwaniami:

Header always set X-Frame-Options SAMEORIGIN


zostało wspomniane wcześniej - patrz komentarz @Jay do odpowiedzi stackoverflow.com/a/6767901/1875965
Sandra

Konfiguruję nagłówek pliku .conf zawsze ustawiam opcje X-Frame SAMEORIGIN!
GeekHades

Ale w jaki sposób ma to znaczenie dla pytania tutaj, gdzie nagłówek pochodzi z obcych serwerów, bezpośrednio do klienta , IOW nawet twój własny serwer nie jest zaangażowany? Czy coś brakuje?
Sz.

1

Jedyną prawdziwą odpowiedzią, jeśli nie kontrolujesz nagłówków źródła, które chcesz w ramce iframe, jest jej proxy. Niech serwer będzie działał jak klient, otrzyma źródło, usunie problematyczne nagłówki, w razie potrzeby doda CORS, a następnie pinguje własny serwer.

Jest jeszcze jedna odpowiedź wyjaśniająca, jak napisać taki serwer proxy. Nie jest to trudne, ale byłem pewien, że ktoś musiał to zrobić wcześniej. Z jakiegoś powodu trudno było go znaleźć.

W końcu znalazłem kilka źródeł:

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

^ preferowane. Jeśli potrzebujesz rzadkiego użycia, myślę, że możesz po prostu użyć jego aplikacji heroku. W przeciwnym razie jest to kod do samodzielnego uruchomienia na własnym serwerze. Pamiętaj, jakie są limity.

whatorigin.org

^ drugi wybór, ale dość stary. podobno nowszy wybór w pythonie: https://github.com/Eiledon/alloworigin

wtedy jest trzeci wybór:

http://anyorigin.com/

Co wydaje się pozwalać na trochę bezpłatne korzystanie, ale spowoduje umieszczenie cię na publicznej liście wstydu, jeśli nie zapłacisz i użyjesz nieokreślonej kwoty, z której możesz usunąć tylko, jeśli uiścisz opłatę ...


0

Nie wspomniano, ale może pomóc w niektórych przypadkach:

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

Użyj tej linii podanej poniżej zamiast header()funkcji.

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

0

miałem ten problem i rozwiązałem go edytując 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>

zmieniłem SAMEORIGIN na GOFORIT i zrestartowałem serwer


-1

Spróbuj tego, nie sądzę, żeby ktokolwiek sugerował to w temacie, rozwiąże to jak 70% twojego problemu, w przypadku niektórych innych stron musisz złomować, mam pełne rozwiązanie, ale nie jest to publiczne,

DODAJ poniżej do swojego elementu iframe

sandbox = "allow-same-origin-enable-scripts allow-popups allow-form"


1
piaskownica zmniejsza uprawnienia, nie dodaje ich. patrz html5rocks.com/en/tutorials/security/sandboxed-iframes
Kyle Baker

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.