Estoy escribiendo una aplicación de Facebook basada en iframes. Ahora quiero usar la misma página html para renderizar el sitio web normal y la página de lienzo dentro de Facebook. Quiero saber si puedo determinar si la página se ha cargado dentro del iframe o directamente en el navegador.
¿Cómo identificar si una página web se está cargando dentro de un iframe o directamente en la ventana del navegador?
Los navegadores pueden bloquear el acceso window.topdebido a la misma política de origen . Los errores de IE también tienen lugar. Aquí está el código de trabajo:
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
topy selfson ambos windowobjetos (junto con parent), por lo que está viendo si su ventana es la ventana superior.
RoBorg es correcto, pero quería agregar una nota al margen.
En IE7 / IE8 cuando Microsoft agregó pestañas a su navegador, rompieron una cosa que causará estragos en su JS si no tiene cuidado.
Imagine este diseño de página:
MainPage.html
IframedPage1.html (named "foo")
IframedPage2.html (named "bar")
IframedPage3.html (named "baz")
Ahora en el cuadro "baz", haga clic en un enlace (sin objetivo, se carga en el cuadro "baz"), funciona bien.
Si la página que se carga, vamos a llamarla special.html, usa JS para verificar si "it" tiene un marco principal llamado "bar", devolverá verdadero (esperado).
Ahora digamos que la página special.html cuando se carga, verifica el cuadro principal (para la existencia y su nombre, y si es "barra", se recarga en el marco de la barra, por ejemplo,
if(window.parent && window.parent.name == 'bar'){
window.parent.location = self.location;
}
Hasta aquí todo bien. Ahora viene el error.
Digamos que en lugar de hacer clic en el enlace original como normal y cargar la página special.html en el marco "baz", haces clic en el medio o eliges abrirlo en una nueva pestaña.
Cuando se cargue esa nueva pestaña (¡ sin marcos principales en absoluto! ) ¡ IE ingresará un ciclo sin fin de carga de páginas! porque IE "copia" la estructura de marco en JavaScript de modo que la nueva pestaña TIENE un padre y ese padre TIENE el nombre "barra".
La buena noticia es que revisa:
if(self == top){
//this returns true!
}
en esa nueva pestaña se devuelve verdadero, y por lo tanto puede probar esta extraña condición.
Como usted pregunta en el contexto de una aplicación de Facebook, es posible que desee considerar detectar esto en el servidor cuando se realiza la solicitud inicial. Facebook pasará un montón de datos de cadena de consulta, incluida la clave fb_sig_user si se llama desde un iframe.
Debido a que probablemente necesite verificar y usar esta información de todos modos en su aplicación, utilícela para determinar el contexto apropiado para procesar.
Utilice esta función JavaScript como un ejemplo de cómo lograr esto.
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 respuesta aceptada no funcionó para mí dentro de la escritura de contenido de una extensión de Firefox 6.0 (Addon-SDK 1.0): Firefox ejecuta el script contenido en cada una: la ventana de nivel superior y en todos los marcos flotantes.
Dentro de la escritura de contenido consigo los siguientes resultados:
(window !== window.top) : false
(window.self !== window.top) : true
Lo extraño de esta salida es que es siempre el mismo, independientemente de si el código se ejecuta el interior de una ventana de nivel superior o iframe.
Por otro lado Google Chrome parece para ejecutar mi script contenido de una sola vez dentro de la ventana de nivel superior, lo que lo anterior no funcionaría en absoluto.
Lo que finalmente trabajado para mí en un script contenido en ambos navegadores es la siguiente:
console.log(window.frames.length + ':' + parent.frames.length);
Sin iframes este grabados 0:0, en una ventana de nivel superior que contiene un cuadro que se imprime 1:1, y en el único marco flotante de un documento que se imprime 0:1.
Esto permite que mi extensión para determinar en ambos navegadores si hay algún iframes presente, y, además, en Firefox si se ejecuta dentro de uno de los marcos flotantes.
Es una antigua pieza de código que he usado un par de veces:
if (parent.location.href == self.location.href) {
window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}
Estoy usando la siguiente:
var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
if (window.frames.length != parent.frames.length) { page loaded in iframe }
Pero sólo si el número de marcos flotantes difiere en su página y la página que se va a cargar en el iframe. No nos iframe en tu sitio para tener garantía del 100% del resultado de este código
Escribir este JavaScript en cada página
if (self == top)
{ window.location = "Home.aspx"; }
A continuación, se redirige automáticamente a la página principal.
Si desea saber si el usuario está accediendo a la aplicación de la pestaña de la página de facebook o en cheque de la lona para la solicitud firmada. Si no lo consigue, probablemente el usuario no tiene acceso a Facebook. Para asegurarse de que confirman la estructura campos signed_request y campos de contenido.
Con el php-SDK se puede obtener la solicitud firmada así:
$signed_request = $facebook->getSignedRequest();
Puede leer más sobre solicitud firmada aquí:
https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/
y aquí:
https://developers.facebook.com/docs/reference/login/signed-request/
window.frameElementDevuelve el elemento (por ejemplo, <iframe> o <object>) en la que está incrustada la ventana, o null si la ventana es de nivel superior. Por lo tanto la identificación de código es el siguiente
if (window.frameElement) {
// in frame
}
else {
// not in frame
}
Esta es la norma y bastante nuevo método. Funciona exactamente en Chrome y Firefox. No puedo recomendar como solución universal, pero se debe mencionar aquí que pienso.
De hecho, me utiliza para comprobar window.parent y funcionó para mí, pero últimamente ventana es un objeto cíclico y siempre tiene una clave principal, iframe o ningún marco flotante.
Como sugiere el comentario dura comparando con obras window.parent. No estoy seguro si esto va a funcionar si iframe es exactamente la misma página web como padre.
window === window.parent;
No estoy seguro de cómo funciona este ejemplo para los más viejos navegadores web pero yo lo uso para IE, Firefox y Chrome sin y número:
var iFrameDetection = (window === window.parent) ? false : true;
Mejor-por-ahora Marco navegadores antiguos de escritura Breaking
Las otras soluciones no trabajaron para mí. Esta funciona en todos los navegadores:
Una manera de defenderse contra el clickjacking es incluir un guión "marco automático" en cada página que no debe ser enmarcado. La siguiente metodología evitará que una página web sea enmarcado incluso en navegadores antiguos, que no son compatibles con el X-Frame-Opciones-cabecera.
En el elemento de documento CABEZA, añada lo siguiente:
<style id="antiClickjack">body{display:none !important;}</style>
En primer lugar aplicar un ID para el elemento de estilo en sí:
<script type="text/javascript">
if (self === top) {
var antiClickjack = document.getElementById("antiClickjack");
antiClickjack.parentNode.removeChild(antiClickjack);
} else {
top.location = self.location;
}
</script>
De esta manera, todo puede estar en el encabezado del documento y sólo necesita un método / taglib en su API.
Referencia: https://www.codemagi.com/blog/post/194
Esto terminó siendo la solución más simple para mí.
<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>













