Estoy escribiendo una aplicación de Facebook basada en iframe. 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?
Respuesta
Los navegadores pueden bloquear el acceso a window.top
debido a same origin policy. 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;
}
}
top
y self
son ambos window
objetos (junto con parent
), por lo que se está viendo si la 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.
Imagínese este diseño de página:
MainPage.html
IframedPage1.html (named "foo")
IframedPage2.html (named "bar")
IframedPage3.html (named "baz")
ahora en el marco de "baz" hace clic en un enlace (sin objetivo, cargas en el marco de "baz") que trabaja muy 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 carga, comprueba el marco padre (por la existencia y su nombre, y si es "barra" se vuelven a cargar en sí en el marco de la barra. Ej
if(window.parent && window.parent.name == 'bar'){
window.parent.location = self.location;
}
hasta aquí todo bien. Ahora viene el fallo.
permite decir en lugar de hacer clic en el enlace original como normal, y la carga de la página special.html en el "Baz" marco, medio-clic o eligió ábralo en una nueva pestaña.
Cuando esa nueva pestaña se carga (sin ningún cuadro principal).) ¡IE introducirá un bucle infinito de carga de página! porque IE "copia sobre" 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 la comprobación:
if(self == top){
//this returns true!
}
en que la nueva ficha de vuelta verdad, y por lo tanto se puede probar esta situación extraña.
¿Se ha solucionado el error mientras tanto? No puedo reproducirlo en IE8. Siempre obtengo el 'window.parent' correcto. – user123444555621
No estoy seguro - Ejecutaré mi suite de pruebas contra IE9 y abajo nuevamente y publicaré una actualización. – scunliffe
@scunliffe - ¿Alguna actualización? – Nick
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.
Dado que probablemente necesite verificar y utilizar esta información de todos modos en su aplicación, utilícela para determinar el contexto apropiado para representar.
Utilice esta función de Javascript como 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 la secuencia de comandos contenidos en cada uno: 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 dentro de una la ventana de nivel superior de marco flotante o.
Por otro lado, Google Chrome parece ejecutar mi script de contenido solo una vez dentro de la ventana de nivel superior, por lo que lo anterior no funcionaría en absoluto.
Lo que finalmente trabajó para mí en un script contenido en ambos navegadores es la siguiente:
console.log(window.frames.length + ':' + parent.frames.length);
Sin iframes Esto imprime 0:0
, en una ventana de nivel superior que contiene un cuadro que imprime 1:1
, y en el único iframe de un documento imprime 0:1
.
Esto permite a mi extensión determinar en ambos navegadores si hay algún iframes presente, y adicionalmente en Firefox si se ejecuta dentro de uno de los iframes.
Pruebe 'document.defaultView.self === document.defaultView.top' o' window! == window.top'. En el script de contenido del SDK complementario de Firefox, el objeto 'self' global es un objeto utilizado para comunicarse con el script principal. –
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';
}
Debido a la lectura de XSS, no se permite la ubicación principal. –
Para agregar a Eneko Alonso: esto funciona '(parent.location == self.location)' –
@piotr_cz, funciona solo si la política del mismo origen permite el acceso a 'parent.location'. De lo contrario, se lanza una excepción – Dan
estoy usando esto:
var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
¿Por qué haces esto: '.indexOf (" HTMLIFrameElement ")'? – Luke
.indexOf ('foobarbaz')> -1 es una forma de comprobar si hay "coincidencia de subcadena" (es decir, ¿se puede encontrar 'foobarbaz' en algún lugar dentro de la cadena?), Pero sin usar expresiones regulares. Es lógicamente equivalente a .match (/ foobarbaz /). Se usa para :-) trabajar en un rango más amplio de navegadores, y todavía se puede usar por hábito o por el rendimiento de la maquinaria de expresión regular. –
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 página que lo están cargando en iframe. No nos iframe en tu sitio para tener garantía del 100% del resultado de este código
No es una solución muy elegante para determinar si la ventana está dentro de un iframe o no, y tampoco hay garantía de que pueda leer desde parent.frames. – Percy
escribir este JavaScript en cada página
if (self == top)
{ window.location = "Home.aspx"; }
entonces se redirige automáticamente a la página principal.
Su redirección funcionará cuando no esté si el marco. Entonces no podría navegar en su sitio. En segundo lugar, existen técnicas para evitar el redireccionamiento desde la página principal. –
Si desea saber si el usuario está accediendo a su aplicación desde la pestaña de la página de Facebook o el lienzo, compruebe la Solicitud firmada. Si no lo obtiene, probablemente el usuario no esté accediendo desde Facebook. Para asegurarse de confirmar la estructura de los campos signed_request y el contenido de los campos.
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.frameElement
Devuelve el elemento (como <iframe> o <objeto>) en el que está incrustada la ventana, o nulo si la ventana está en el nivel superior. Así código de identificación parece
if (window.frameElement) {
// in frame
}
else {
// not in frame
}
This is standard
and rather new
method.
Funciona exactamente en Chrome y Firefox. No puedo recomendarlo como una solución universal, pero debería mencionarse aquí, creo.
Nota: intentar leer 'frameElement' arrojará una excepción SecurityError en iframes de origen cruzado, de acuerdo con [W3C] (https://www.w3.org/TR/html5/browsers.html#dom-frameelement) ([WHATWG ] (https://html.spec.whatwg.org/multipage/browsers.html#dom-frameelement) dice que debería devolver nulo en su lugar). Así que es posible que desee envolverlo en una declaración 'try ... catch'. – Oriol
'Este es un método [...] bastante nuevo' <- a través de su enlace, dice IE5.5. Probé en IE9, parece funcionar bien. – Neolisk
esto realmente no funciona – user151496
if(typeof(parent) == 'undefined') {
console.log('Not Iframe');
}
else {
console.log('iframe');
}
Estos no son trabajos en opera mini 11 – Serg
en cromo en el contexto de la ventana principal 'window.parent === window' es verdadero. Entonces tu respuesta es incorrecta. Y esta comparación podría usarse para verificar (al menos en Chrome, no lo probó en otros navegadores). – MarkosyanArtur
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;
O simplemente '! (Ventana === window.parent)' – CalculatorFeline
- 1. Detectar si una página está dentro de un iframe - servidor
- 2. Crear un navegador de ventana dentro del navegador con extjs
- 3. Compruebe si la ventana primaria es iframe o no
- 4. ¿Cómo puedo detectar si una ventana del navegador está enfocada o no?
- 5. ¿Cómo ejecutar jQuery directamente en cualquier página del navegador?
- 6. Comprobar si la página está en Iframe para Google Chrome
- 7. Web scraping - cómo identificar contenido principal en una página web
- 8. Incrustar ventana del navegador web en Java
- 9. ¿Cómo identificar que se está ejecutando en una máquina virtual?
- 10. iframe click link se abre en la página principal en lugar de en la página iframe
- 11. Detección del lado del servidor de que se muestra una página dentro de un IFrame
- 12. Limitaciones de página web cuando se envuelve dentro de un IFrame?
- 13. ¿Cómo implementar una página web que se escala cuando se cambia el tamaño de la ventana del navegador?
- 14. Evitar # ancla en un iframe al desplazarse por la ventana del navegador
- 15. ¿Existe alguna manera confiable de determinar si una pestaña o ventana del navegador está inactiva o no está enfocada?
- 16. ¿Cómo obtener un objeto superior (ventana o página) en WPF?
- 17. window.history.back() vuelve a cargar la página en Internet Explorer cuando está dentro de un iframe?
- 18. ¿Cómo identificar si la carpeta está abierta?
- 19. Mostrar PDF dentro del navegador web
- 20. Haciendo que la imagen del pie de página se adhiera a la parte inferior del navegador web o página
- 21. Página de inicio del navegador web Android
- 22. ¿Cómo mostrar el mensaje de carga cuando un iFrame se está cargando?
- 23. ¿Cómo identificar si un usuario está siendo suplantado en Symfony2?
- 24. ¿Cómo saber la diferencia entre cargar un iframe o cargar una página completa en un UIWebView?
- 25. ¿Alguna forma de identificar la pestaña del navegador en JavaScript?
- 26. Cómo detectar si una página web se está ejecutando desde un sitio web o sistema de archivos local
- 27. Detectar dentro del navegador Android o WebView
- 28. ¿Cómo cambiar la altura del iframe en función del contenido dinámico dentro del iframe?
- 29. ¿Cómo puedo cargar una página web dentro de la vista web del fajo telefónico?
- 30. ¿Cómo comprobar si la página web está desplazada?
Esto parece funcionar bien en Firefox. ¿Funciona en otros navegadores también? – akshat
Tener una página con un iframe dentro de un iframe, para probar el iframe de mi hijo si mi iframe primario estaba incrustado en la página, lo usé if (parent === top) – sglessard
@sglessard Si la página secundaria y parent son de dominios diferentes entonces Firefox se quejará por la Política de Same Origin (www.w3.org/Security/wiki/Same_Origin_Policy) y el código no funcionará –