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?
Come identificare se una pagina web viene caricata all'interno di un iframe o direttamente nella finestra del browser?
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.
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.
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.
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;
}
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.
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';
}
Sto usando questo:
var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
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
Scrivere questo javascript in ogni pagina
if (self == top)
{ window.location = "Home.aspx"; }
Poi si reindirizza automaticamente alla home page.
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/
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.
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;
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;
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
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>













