Come identificare se una pagina web viene caricata all'interno di un iframe o direttamente nella finestra del browser?

voti
450

Sto scrivendo un'applicazione Facebook iframe base. Ora voglio usare la stessa pagina html per rendere il normale sito web così come la pagina di tela all'interno di Facebook. Vorrei sapere se posso determinare se la pagina è stata eseguita all'interno del iframe o direttamente nel browser?

È pubblicato 28/11/2008 alle 16:45
fonte dall'utente
In altre lingue...                            


15 risposte

voti
840

I browser possono bloccare l'accesso a window.topcausa di politica stessa origine . Bug di IE anche avvengono. Ecco il codice di lavoro:

function inIframe () {
    try {
        return window.self !== window.top;
    } catch (e) {
        return true;
    }
}

tope selfsono entrambi windowoggetti (insieme parent), in modo che stai vedendo se la finestra è la finestra in alto.

Risposto il 28/11/2008 a 16:47
fonte dall'utente

voti
25

RoBorg è corretto, ma ho voluto aggiungere una nota a margine.

In IE7 / IE8 quando Microsoft ha aggiunto Tabs per il proprio browser hanno rotto una cosa che causerà il caos con i tuoi JS, se non si sta attenti.

Immaginate questo layout di pagina:

MainPage.html
  IframedPage1.html   (named "foo")
  IframedPage2.html   (named "bar")
    IframedPage3.html (named "baz")

Ora, in frame "baz" si fa clic su un collegamento (nessun obiettivo, carichi nella cornice "baz") funziona benissimo.

Se la pagina che viene caricato, consente di chiamare special.html, usa JS per verificare se "esso" ha una struttura genitore denominato "bar" che restituirà true (expected).

Ora consente di dire che la pagina special.html quando viene caricato, controlla il frame genitore (per l'esistenza e il suo nome, e se si tratta di "bar" esso si ricarica nella cornice bar. Es

if(window.parent && window.parent.name == 'bar'){
  window.parent.location = self.location;
}

Fin qui tutto bene. Ora arriva il bug.

Diciamo invece di cliccare sul link originale, come normale, e il caricamento della pagina special.html nel frame "baz", è mezza cliccato o scelto di aprirlo in una nuova scheda.

Quando che i nuovi carichi di tabulazione ( senza cornici genitore a tutti! ) IE entrerà un ciclo infinito di caricamento della pagina! perché IE "copie oltre" la struttura del telaio in JavaScript in modo tale che la nuova scheda ha un genitore, e quel genitore ha il nome di "bar".

La buona notizia, è che il controllo:

if(self == top){
  //this returns true!
}

in quella nuova scheda fa ritorno vero, e in tal modo è possibile verificare questa condizione strana.

Risposto il 28/11/2008 a 18:53
fonte dall'utente

voti
1

Dal momento che si stanno chiedendo nel contesto di un'applicazione Facebook, si potrebbe prendere in considerazione rilevare questo al server quando la richiesta iniziale è fatto. Facebook passerà lungo un po 'di querystring dati tra cui la chiave fb_sig_user se viene chiamato da un iframe.

Dato che probabilmente è necessario controllare e utilizzare questi dati in ogni caso nella vostra app, utilizzarlo per determinare il contesto appropriato per il rendering.

Risposto il 11/12/2008 a 23:04
fonte dall'utente

voti
2

Usare questa funzione JavaScript come un esempio su come raggiungere questo obiettivo.

function isNoIframeOrIframeInMyHost() {
// Validation: it must be loaded as the top page, or if it is loaded in an iframe 
// then it must be embedded in my own domain.
// Info: IF top.location.href is not accessible THEN it is embedded in an iframe 
// and the domains are different.
var myresult = true;
try {
    var tophref = top.location.href;
    var tophostname = top.location.hostname.toString();
    var myhref = location.href;
    if (tophref === myhref) {
        myresult = true;
    } else if (tophostname !== "www.yourdomain.com") {
        myresult = false;
    }
} catch (error) { 
  // error is a permission error that top.location.href is not accessible 
  // (which means parent domain <> iframe domain)!
    myresult = false;
}
return myresult;
}
Risposto il 21/09/2011 a 03:32
fonte dall'utente

voti
16

La risposta accettata non ha funzionato per me all'interno dello script contenuto di un Firefox 6.0 Extension (Addon-SDK 1.0): Firefox esegue lo script contenuti in ciascuna: la finestra di primo livello e in tutte le iframe.

All'interno dello script contenuti ottengo i seguenti risultati:

 (window !== window.top) : false 
 (window.self !== window.top) : true

La cosa strana di questa uscita è che è sempre lo stesso indipendentemente dal fatto che il codice viene eseguito all'interno di un iframe o la finestra di primo livello.

D'altra parte Google Chrome sembra per eseguire il mio script contenuti solo una volta all'interno della finestra di primo livello, in modo da quanto sopra non avrebbe funzionato affatto.

Ciò che alla fine ha funzionato per me in uno script contenuti in entrambi i browser è questo:

 console.log(window.frames.length + ':' + parent.frames.length);

Senza iframe Questo stampa 0:0, in una finestra di livello superiore contenente un fotogramma viene stampato 1:1, e nell'unica iframe di un documento viene stampato 0:1.

In questo modo la mia estensione di determinare in entrambi i browser se ci sono iframe presenti, e in aggiunta in Firefox se viene eseguito all'interno di una delle iframe.

Risposto il 14/10/2011 a 15:32
fonte dall'utente

voti
-1

Si tratta di un antico pezzo di codice che ho usato un paio di volte:

if (parent.location.href == self.location.href) {
    window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}
Risposto il 25/10/2011 a 04:57
fonte dall'utente

voti
5

Sto usando questo:

var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
Risposto il 20/06/2012 a 11:04
fonte dall'utente

voti
-3
if (window.frames.length != parent.frames.length) { page loaded in iframe }

Ma solo se il numero di iframe differisce nella tua pagina e la pagina che si sta caricando in iframe. Non fare iframe nella pagina per avere il 100% di garanzia del risultato di questo codice

Risposto il 27/10/2012 a 16:31
fonte dall'utente

voti
-4

Scrivere questo javascript in ogni pagina

if (self == top)
  { window.location = "Home.aspx"; }

Poi si reindirizza automaticamente alla home page.

Risposto il 08/02/2013 a 07:15
fonte dall'utente

voti
0

Se volete sapere se l'utente sta accedendo tua app dalla scheda pagina di facebook o assegno tela per la richiesta firmata. Se non si ottiene, probabilmente l'utente non accede da facebook. Per assicurarsi che confermano la signed_request struttura di campi e campi contenuti.

Con il php-sdk è possibile ottenere la richiesta firmata in questo modo:

$signed_request = $facebook->getSignedRequest();

Si può leggere di più su Firmato Richiesta qui:

https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/

e qui:

https://developers.facebook.com/docs/reference/login/signed-request/

Risposto il 17/06/2013 a 19:08
fonte dall'utente

voti
64

window.frameElementRestituisce l'elemento (ad esempio <iframe> o <object>) in cui è incorporata la finestra, oppure null se la finestra è di primo livello. Quindi, l'identificazione codice è simile

if (window.frameElement) {
  // in frame
}
else {
  // not in frame
}

Questo è lo standard e piuttosto nuovo metodo. Funziona esattamente in Chrome e Firefox. Non posso consigliarlo come soluzione universale, ma va ricordato qui credo.

Risposto il 07/09/2013 a 23:55
fonte dall'utente

voti
1

Ho utilizzato per controllare WINDOW.PARENT e ha funzionato per me, ma ultimamente la finestra è un oggetto ciclico e ha sempre una chiave padre, iframe o no iframe.

Come suggeriscono i commenti difficile il confronto con opere WINDOW.PARENT. Non sono sicuro se questo funziona se iframe è esattamente la stessa pagina web come genitore.

window === window.parent;
Risposto il 04/03/2014 a 04:47
fonte dall'utente

voti
3

Non sono sicuro di come questo esempio funziona per i browser Web più anziani, ma io uso questo per IE, Firefox e Chrome senza ed emissione:

var iFrameDetection = (window === window.parent) ? false : true;
Risposto il 19/11/2015 a 09:30
fonte dall'utente

voti
0

Best-per-ora Legacy Browser Telaio rottura Script

Le altre soluzioni non hanno lavorato per me. Questo funziona su tutti i browser:

Un modo per difendersi da clickjacking è quello di includere uno script di "frame-breaker" in ogni pagina che non deve essere inquadrata. Il seguente metodologia impedirà una pagina web di essere incorniciato anche nei browser legacy, che non supportano l'X-Frame-Options-Header.

Nel documento, elemento HEAD, aggiungere il seguente:

<style id="antiClickjack">body{display:none !important;}</style>

In primo luogo applicare un ID all'elemento stile stesso:

<script type="text/javascript">
   if (self === top) {
       var antiClickjack = document.getElementById("antiClickjack");
       antiClickjack.parentNode.removeChild(antiClickjack);
   } else {
       top.location = self.location;
   }
</script>

In questo modo, tutto può essere nell'intestazione del documento e hai solo bisogno di un metodo / taglib nella vostra API.

Riferimento: https://www.codemagi.com/blog/post/194

Risposto il 12/04/2018 a 09:24
fonte dall'utente

voti
0

Questo ha finito di essere la soluzione più semplice per me.

    <p id="demofsdfsdfs"></p>

<script>

if(window.self !== window.top) {

//run this code if in an iframe
document.getElementById("demofsdfsdfs").innerHTML = "in frame";

}else{

//run code if not in an iframe
document.getElementById("demofsdfsdfs").innerHTML = "no frame";
}

</script>
Risposto il 25/07/2018 a 01:15
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more