Superare "Display vietato da X-Frame-Options"


420

Sto scrivendo una piccola pagina web il cui scopo è quello di inquadrare alcune altre pagine, semplicemente per consolidarle in una singola finestra del browser per facilitare la visualizzazione. Alcune delle pagine che sto cercando di inquadrare vietano di essere incorniciate e lanciano un "Rifiuto di visualizzare il documento perché visualizzazione vietata da X-Frame-Options". errore in Chrome. Comprendo che si tratta di un limite di sicurezza (per una buona ragione) e non ho accesso a modificarlo.

Esiste un metodo di framing o non framing alternativo per visualizzare le pagine all'interno di una singola finestra che non verrà bloccato dall'intestazione X-Frame-Options?


117
Se sono le tue pagine, rimuovi il limitatore di frame. Altrimenti, rispetta i desideri dell'autore della pagina e NON FACILITARLI.
Marc B,

Se ricevi questo errore per un'app di Facebook e usi le chiamate AJAX, ho letto da qualche parte che a Facebook piace davvero usare i tag # per il suo contatto Ajax quindi prova a cambiare i collegamenti, ha funzionato per me.
eric.itzhak,

28
@MarcB Chrome e Firefox incorniciano eticamente i siti Web non di proprietà in Chrome dell'interfaccia utente nativa. Questi programmi consentono anche politiche rilassate della stessa origine ai loro proprietari, FWIW. Come ha detto garen-checkly, "Sto scrivendo una minuscola pagina web il cui scopo è di inquadrare alcune altre pagine, semplicemente per consolidarle in una singola finestra del browser per facilitare la visualizzazione". Questo in pratica estende il browser Web e sarebbe completamente etico. L'intento dichiarato non è diverso dalla scrittura di uno script bash per aprire e disporre le finestre del browser.
Samuel Danielson,

1
Controlla Surfly . Può fare esattamente quello che ti serve.
muodov,

1
@MarcB Non è utile. OP potrebbe non preoccuparsi dei desideri dell'autore della pagina.
flarn2006,

Risposte:


211

Ho avuto un problema simile, in cui stavo cercando di visualizzare il contenuto del nostro sito in un iframe (come una finestra di dialogo in stile lightbox con Colorbox ) e in cui era presente un'intestazione "X-Frame-Options SAMEORIGIN" a livello di server sul server di origine che ne impedisce il caricamento sul nostro server di prova.

Questo non sembra essere documentato da nessuna parte, ma se puoi modificare le pagine che stai provando a iframe (ad esempio, sono le tue pagine), semplicemente inviando un'altra intestazione X-Frame-Options con qualsiasi stringa disabilita i comandi SAMEORIGIN o DENY.

per esempio. per PHP, mettendo

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

nella parte superiore della tua pagina i browser uniranno i due, il che si tradurrà in un'intestazione di

X-Frame-Options SAMEORIGIN, GOFORIT

... e ti permette di caricare la pagina in un iframe. Questo sembra funzionare quando il comando SAMEORIGIN iniziale è stato impostato a livello di server e si desidera sovrascriverlo caso per pagina.

Ti auguro il meglio!


3
Ho avuto una cornice attorno a un sito Web. Sul mio sito Web, sto reindirizzando a Instagram per OAUTH. Dal momento che Instagram invia X-Frame-Options: SAMEORIGINnon c'è modo di farlo all'interno del frame. Devi usare un popup.
Steve Tauber,

16
Con PHP è probabilmente meglio usare la nuova header_removefunzione, a condizione che sia disponibile (> = 5.3.0).
un gatto

11
Oppure puoi modificare .htaccess se vuoi rimuovere X-Frame-Options da un'intera directory. Basta aggiungere la riga:Header always unset X-Frame-Options
Jay

4
@cawecoy: Beh, sì, il punto è che non è valido. Si basa sul fatto che i browser ignorano l'intestazione non valida e "non si aprono", il che è un comportamento non specificato e piuttosto complicato su cui fare affidamento. GOFORIT(o altro token non valido arbitrario casuale) sta deliberatamente rompendo una misura di sicurezza applicata da un server; se hai il controllo del server (cosa che dovresti fare per qualsiasi vero servizio pubblico), la cosa giusta da fare è semplicemente impostare il server in modo da non impostare l'intestazione in primo luogo.
bobince

31
Questo non sembra funzionare più in Chrome. Valori non validi fanno in modo che il valore predefinito sia DENY.
jamesfm,

159

Se ricevi questo errore per un video di YouTube, anziché utilizzare l'URL completo, utilizza l'URL di incorporamento dalle opzioni di condivisione. Sembreràhttp://www.youtube.com/embed/eCfDxZxTBW4

È inoltre possibile sostituire watch?v=con embed/così http://www.youtube.com/watch?v=eCfDxZxTBW4diventahttp://www.youtube.com/embed/eCfDxZxTBW4


14
Oh progresso ... Vorrei che ci reindirizzassero alla pagina di incorporamento invece di causare un errore da lanciare e facendomi riscrivere i miei script!
Joeytwiddle,

122

Se viene visualizzato questo errore durante il tentativo di incorporare una mappa di Google in un iframe, è necessario aggiungere &output=embedal collegamento di origine.


120
Questo è vero solo per incorporare google maps in un iframe e non una "soluzione" generale.
Benjamin Wohlwend,

17
Avevo bisogno di incorporare una google map in un lightbox, quindi questa "soluzione" era perfetta
yitwail,

5
Se stai cercando di farlo con un intento web di Twitter, dimenticalo. Ho appena perso tutto il giorno a provare diversi plug-in lightbox solo per scoprire questo "Sebbene sia possibile fornire collegamenti a intenti all'interno di IFRAME e widget, le pagine risultanti non possono essere caricate in un IFRAME." Fonte: sito Web Twitter.
Gubatron,

6
Questo non funziona se stai cercando di caricare l'iframe src dopo che il resto della pagina è stato caricato anche se aggiungi&output=embed
pathfinder

1
@pathfinder Questo ha funzionato per me quando ho avuto problemi a caricare l'iframe src dopo che la pagina era stata caricata
David Sykes

61

AGGIORNAMENTO 2019: È possibile by-pass X-Frame-Optionsin un <iframe>utilizzando solo JavaScript lato client e il mio X-Frame-bypass Web Component. Ecco una demo: Hacker News in unX-Frame-Bypass . (Testato su Chrome e Firefox.)


3
Questa è una soluzione interessante. Funziona bene in FF / Chrome / Opera ma non funziona in IE / Edge. Chiunque sappia qualcosa che lo farà?
Collezionista,

7
Questo non funziona più. Dà "Rifiutato di visualizzare ' news.ycombinator.com ' in un frame perché imposta 'X-Frame-Options' su 'DENY'." come previsto
g.pickardou,

2
@ g.pickardou Funziona per me in Google Chrome 46, posso vedere Hacker News in un iframe.
Niutech,

1
@niutech quel violino funziona dopo aver ricaricato la pagina in Chrome 64, ma la prima volta che carico la pagina non funziona. (Prova in incognito.)
Carl Walsh,

1
Grazie, è fantastico!
Andrew Gans,

23

Aggiunta di a

  target='_top'

al mio link nella scheda facebook risolto il problema per me ...


1
Ho avuto lo stesso problema con l'iframe Paypal contenuto in un altro iframe. Ora funziona! Grazie
Fabrizio Fortino,

4
Ho anche aggiunto target = '_ top', ma il problema con questa soluzione è che il link ora si apre all'esterno dell'iframe in una nuova scheda senza Facebook Canvas.
sumitkanoje,



13

Ho avuto lo stesso problema quando ho provato a incorporare moodle 2 in iframe, la soluzione è Site administration ► Security ► HTTP securitye controllaAllow frame embedding


ben fatto per il metodo moodle, poiché gli altri metodi falliscono / vengono sovrascritti.
ericosg,

7

Questa è la soluzione ragazzi !!

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

L'unica cosa che ha funzionato per le app di Facebook!



6

Soluzione per caricare un sito Web esterno in un iFrame anche se l'opzione x-frame è impostata per negare sul sito Web esterno.

Se desideri caricare un altro sito Web in un iFrame e ricevi l' Display forbidden by X-Frame-Options”errore, puoi effettivamente superarlo creando uno script proxy sul lato server.

L' srcattributo di iFrame potrebbe avere un URL simile al seguente:/proxy.php?url=https://www.example.com/page&key=somekey

Quindi proxy.php sarebbe simile a:

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

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

Questo passa il blocco, perché è solo una richiesta GET che potrebbe essere stata una normale visita alla pagina del browser.

Attenzione: potresti voler migliorare la sicurezza in questo script. Perché gli hacker potrebbero iniziare a caricare pagine Web tramite lo script proxy.


Lo stavo facendo alcune settimane fa e tutti gli URL relativi utilizzati nella pagina esterna non funzionano quando si utilizza echo. (Tipicamente CSS e / o JS, quindi potresti non avere la piena funzionalità a meno che non modifichi gli URL prima dell'eco.) A meno che non mi sia perso qualcosa ...,
ultrageek

Non so perché questo accada per te ... Dovrebbe funzionare come una normale richiesta HTTP, proprio come farebbe un utente finale quando visita l'URL. Quindi il risultato di get_file_contents () dovrebbe essere una pagina HTML completamente funzionante.
Floris

5

Ho provato quasi tutti i suggerimenti. Tuttavia, l'unica cosa che ha davvero risolto il problema è stata:

  1. Crea un .htaccessnella stessa cartella in cui si trova il tuo file PHP.

  2. Aggiungi questa riga all'htaccess:

    Header always unset X-Frame-Options

L'incorporazione del PHP da parte di un iframe da un altro dominio dovrebbe funzionare in seguito.

Inoltre potresti aggiungere all'inizio del tuo file PHP:

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

Il che, tuttavia, non era necessario nel mio caso.


Header disattiva sempre X-Frame-Options in htaccess ha fatto il trucco per me
ujwal dhakal

4

Ho avuto lo stesso problema con mediawiki, questo perché il server ha negato l'incorporamento della pagina in un iframe per motivi di sicurezza.

L'ho risolto scrivendo

$wgEditPageFrameOptions = "SAMEORIGIN"; 

nel file di configurazione php di mediawiki.

Spero che sia d'aiuto.


3

FWIW:

Abbiamo avuto una situazione in cui dovevamo uccidere il nostro iFramequando è apparso questo codice "breaker". Quindi, ho usato PHP function get_headers($url);per controllare l'URL remoto prima di mostrarlo in un iFrame. Per prestazioni migliori, ho memorizzato nella cache i risultati in un file in modo da non stabilire una connessione HTTP ogni volta.


3

Stavo usando Tomcat 8.0.30, nessuno dei suggerimenti ha funzionato per me. Mentre stiamo cercando di aggiornare X-Frame-Optionse impostarlo su ALLOW, ecco come ho configurato per consentire gli iframe di incorporamento:

  • Passare alla directory conf Tomcat, modificare il file web.xml
  • Aggiungi il filtro qui sotto:
<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> 
  • Riavvia il servizio Tomcat
  • Accedi alle risorse usando un iFrame.

2

L'unica domanda che ha un sacco di risposte. Benvenuti alla guida che avrei voluto avere quando mi stavo cacciando per farlo funzionare alle 10:30 di notte il giorno della scadenza ... FB fa alcune cose strane con le app di tela e, beh, sei stato avvisato. Se sei ancora qui e hai un'app Rails che apparirà dietro una tela di Facebook, allora avrai bisogno di:

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

Hai bisogno di un controller per chiamare dalle impostazioni di tela di Facebook, ho usato /canvas/e reso il percorso principale SiteControllerper questa app:


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

fonti

  • La configurazione che penso proviene dall'esempio di omniauth.
  • Il file gem (che è la chiave !!!) proviene da: cose di slide che ho imparato ...
  • Questa domanda dello stack aveva l'intero angolo di Xframe, quindi otterrai uno spazio vuoto se non inserisci questa intestazione nel controller dell'app.
  • E il mio uomo @rafmagana ha scritto questa guida heroku , che ora puoi adottare per le rotaie con questa risposta e le spalle dei giganti con cui cammini.

2

target = '_ parent'

Usando l'idea di Kevin Vella, ho provato ad aggiungere quell'attributo per formare elementi creati dal generatore di pulsanti di PayPal. Ha funzionato per me in modo che Paypal non si aprisse in una nuova finestra / scheda del browser.


Sfortunatamente questo non sembra funzionare anche per il safari.
Wtower,

1

Non sono sicuro di quanto sia rilevante, ma ho costruito un rimedio a questo. Sul mio sito, volevo visualizzare il collegamento in una finestra modale che conteneva un iframe che carica l'URL.

Quello che ho fatto è che ho collegato l'evento click del link a questa funzione javascript. Tutto ciò che fa è fare una richiesta a un file PHP che controlla le intestazioni dell'URL per X-FRAME-Options prima di decidere se caricare l'URL nella finestra modale o reindirizzare.

Ecco la funzione:

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


        }

Ecco il codice del file PHP che lo controlla:

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


?>

Spero che sia di aiuto.


1

Mi sono imbattuto in questo problema durante l'esecuzione di un sito Web wordpress. Ho provato ogni sorta di cose per risolverlo e non ero sicuro di come, in definitiva il problema era perché stavo usando l'inoltro DNS con il mascheramento e i collegamenti a siti esterni non venivano indirizzati correttamente. cioè il mio sito è stato ospitato su http: //123.456.789/index.html ma è stato mascherato per essere eseguito su http://somewebSite.com/index.html . Quando ho inserito http: //123.456.789/index.html nel browser facendo clic su quegli stessi collegamenti non si sono verificati problemi di origine dei fotogrammi X nella console JS, ma è in esecuzione http://somewebSite.com/index.htmlfatto. Per mascherare correttamente è necessario aggiungere i server dei nomi DNS dell'host al servizio del dominio, ad esempio godaddy.com dovrebbe disporre di server dei nomi, ad esempio ns1.digitalocean.com, ns2.digitalocean.com, ns3.digitalocean.com, se lo si fosse utilizzando digitalocean.com come servizio di hosting.


1
Ho finito per fare: remove_action( 'admin_init', 'send_frame_options_header',10);per evitare questo problema ...
Majick,

1

È sorprendente che nessuno qui abbia mai menzionato Apachele impostazioni del server ( *.conffile) o il .htaccessfile stesso come causa di questo errore. Cerca tra i tuoi file .htaccesso di Apacheconfigurazione, assicurandoti di non avere il seguente set su DENY:

Header always set X-Frame-Options DENY

Modificandolo in SAMEORIGIN, le cose funzionano come previsto:

Header always set X-Frame-Options SAMEORIGIN


è stato accennato prima - vedi il commento da @Jay sulla risposta stackoverflow.com/a/6767901/1875965
Sandra

Configuro il file .conf Header imposta sempre X-Frame-Options SAMEORIGIN!
GeekHades,

Ma in che modo questo è rilevante per la domanda qui, in cui l'intestazione proviene da server stranieri , direttamente al client , IOW il tuo server non è nemmeno coinvolto? Mi sto perdendo qualcosa?
Sz.

1

L'unica vera risposta, se non controlli le intestazioni sulla tua fonte che vuoi nel tuo iframe, è di proxy. Fare in modo che un server funga da client, ricevere l'origine, eliminare le intestazioni problematiche, aggiungere CORS se necessario, quindi eseguire il ping del proprio server.

C'è un'altra risposta che spiega come scrivere un tale proxy. Non è difficile, ma ero sicuro che qualcuno avrebbe dovuto farlo prima. È stato difficile trovarlo, per qualche motivo.

Finalmente ho trovato alcune fonti:

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

^ preferito. Se hai bisogno di un uso raro, penso che puoi semplicemente usare la sua app heroku. Altrimenti, è codice per eseguirlo da soli sul proprio server. Nota quali sono i limiti.

whateverorigin.org

^ seconda scelta, ma piuttosto vecchia. scelta presumibilmente più recente in Python: https://github.com/Eiledon/alloworigin

poi c'è la terza scelta:

http://anyorigin.com/

Il che sembra consentire un piccolo utilizzo gratuito, ma ti metterà in un elenco pubblico di vergogna se non paghi e utilizzi un importo non specificato, da cui puoi essere rimosso solo se paghi la tassa ...


0

Non menzionato ma può aiutare in alcuni casi:

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

Utilizzare questa riga indicata di seguito anziché la header()funzione.

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

0

ho avuto questo problema e l'ho risolto modificando 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>

ho cambiato SAMEORIGIN in GOFORIT e ho riavviato il server


-1

Prova questa cosa, non credo che nessuno l'abbia suggerito nell'argomento, questo risolverà come il 70% del tuo problema, per alcune altre pagine, devi scartare, ho la soluzione completa ma non per il pubblico,

AGGIUNGI di seguito al tuo iframe

sandbox = "allow-stessa-origine allow-script allow-popups allow-form"


1
sandboxing riduce i privilegi, non li aggiunge. vedi html5rocks.com/en/tutorials/security/sandboxed-iframes
Kyle Baker

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.