Acceda a la URL principal desde el iframe

187

Bien, tengo una página y en esta página tengo un iframe. Lo que necesito hacer es en la página del iframe, averiguar cuál es la URL de la página principal.

He buscado y sé que esto no es posible si mi página de iframe está en un dominio diferente, ya que es una secuencia de comandos entre sitios. Pero en todas partes que he leído dice que si la página del iframe está en el mismo dominio que la página principal, debería funcionar si lo hago, por ejemplo:

parent.document.location
parent.window.document.location
parent.window.location
parent.document.location.href

... u otros combos similares, ya que parece haber múltiples formas de obtener la misma información.

De todos modos, aquí está el problema. Mi iframe está en el mismo dominio que la página principal, pero no está en el mismo dominio SUB. Entonces por ejemplo tengo

http: // www.mysite.com/pageA.html

y luego mi URL de iframe es

http: // qa-www.mysite.com/pageB.html

Cuando intento obtener la URL de pageB.html(la página del iframe), sigo recibiendo el mismo error de acceso denegado. Entonces, parece que incluso los subdominios cuentan como secuencias de comandos entre sitios, ¿es correcto o estoy haciendo algo mal?

Chronofwar
fuente
¿Puedes pasarlo en la URL del marco? Tales como<iframe src="url?parent=parent-url"></iframe>
Biagio Arobba

Respuestas:

21

Estás en lo correcto. Los subdominios todavía se consideran dominios separados cuando se usan iframes. Es posible pasar mensajes usando postMessage(...), pero otras API de JS se hacen inaccesibles intencionalmente.

También es posible obtener la URL según el contexto. Ver otras respuestas para más detalles.

Dan Herbert
fuente
1
Está bien, eso solo explota. Pero al menos sé que no me estoy volviendo loco :( ah bueno, plan B. gracias. (Y perdón por no poner mis cosas en las etiquetas, gracias por la edición)
chronofwar
9
¿Cómo es esta la respuesta seleccionada? Hay descripciones mucho mejores de posibles soluciones a continuación.
Anoyz
1
¡Convenido! La respuesta a continuación con 80 votos es mucho mejor. Esta respuesta está en la especificación html.
Ligemer
44
PUEDE interactuar entre los 2. Pero debe agregar el siguiente script tanto en el padre como en el iframe: <script> document.domain = "mydomain.com"; </script>
George
2
"Vea otras respuestas para más detalles". jaja es como: no tengo ninguna solución, veo otras respuestas, pero también acepto mi respuesta.
Milad
371

Sí, no está permitido acceder a la URL de la página principal si el iframe y la página principal no están en el mismo (sub) dominio. Sin embargo, si solo necesita la URL de la página principal (es decir, la URL del navegador), puede intentar esto:

var url = (window.location != window.parent.location)
            ? document.referrer
            : document.location.href;

Nota:

window.parent.locationesta permitido; evita el error de seguridad en el OP, que es causado por el acceso a la hrefpropiedad: window.parent.location.hrefprovoca "Bloqueado un marco con origen ..."

document.referrerse refiere a "el URI de la página que se vinculó a esta página". Esto puede no devolver el documento que contiene si alguna otra fuente es lo que determinó la iframeubicación, por ejemplo:

  • Contenedor iframe @ Dominio 1
  • Envía iframe secundario al dominio 2
  • Pero en el iframe secundario ... El dominio 2 redirige al dominio 3 (es decir, para autenticación, tal vez SAML), y luego el dominio 3 vuelve a dirigir al dominio 2 (es decir, mediante el envío del formulario (), una técnica estándar de SAML)
  • Para el iframe secundario document.referrer, será el Dominio 3 , no el Dominio que lo contiene 1

document.locationse refiere a "un objeto de ubicación, que contiene información sobre la URL del documento"; presumiblemente el documento actual , es decir, el iframe actualmente abierto. Cuando window.location === window.parent.location, entonces el iframe hrefes el mismo que el del padre que lo contiene href.

Vaibhav
fuente
1
@jepser eso se debe a que su iframe está dentro de ese iframe. nunca tendrá acceso al marco superior con ese en el medio. los iframes de dominios cruzados anidados son incorrectos en muchos niveles. pero es posible que pueda evitarlo si configura document.domainel marco superior y el más interno. tal vez.
gcb
2
O, un poco más compacto:var url = (parent !== window) ? document.referrer : document.location;
thekingoftruth
2
Tenga en cuenta que no funciona si el contenedor se encuentra en su host local (o más generalmente, si esta página no está abierta por un servidor web) o si se llama por file: //.
Guillaume Renoult
55
Cabe señalar que esto se puede derrotar con el Referer-Policyencabezado.
Dan Atkinson
2
Esto no parece funcionar con el navegador Edge: el referente será una cadena vacía ... stackoverflow.com/questions/24169219/…
Davide Orazio Montersino
52

Acabo de descubrir una solución para este problema que es tan simple y, sin embargo, no he encontrado ninguna discusión que lo mencione. Requiere el control del marco principal.

En su iFrame, diga que quiere este iframe: src = "http://www.example.com/mypage.php"

Bueno, en lugar de HTML para especificar el iframe, use un javascript para construir el HTML para su iframe, obtenga la URL principal a través de javascript "en el momento de la compilación" y envíela como un parámetro GET de url en la cadena de consulta de su objetivo src, como entonces:

<script type="text/javascript">
  url = parent.document.URL;
  document.write('<iframe src="http://example.com/mydata/page.php?url=' + url + '"></iframe>');
</script>

Luego, encuentre una función de análisis de URL de JavaScript que analice la cadena de URL para obtener la variable de URL que busca, en este caso es "url".

Encontré un excelente analizador de cadenas de URL aquí: http://www.netlobo.com/url_query_string_javascript.html

Gregory Lewis
fuente
Esta respuesta combinada con stackoverflow.com/a/7739035/216084 hace el trabajo.
2
Esta fue una sugerencia maravillosa. Para aquellos que escriben el código de iframe html principal, esto sería suficiente. Usamos algo muy similar en nuestro software de píxeles.
Ligemer
¡¡Gracias!! Esta es una solución efectiva que aún respeta las reglas entre sitios.
theUtherSide
¿Pero reescribe todas las URL en el html en el servidor? De lo contrario, cuando un usuario hace clic en un enlace en el iFrame, aún no será accesible.
Roel
@Roel podría escribirlos todos en el momento del servidor (en esencia, "codificar" esta respuesta), o esta respuesta podría hacerlo en JavaScript, por ejemplo, después de que la página cargue, inyecta los iframes deseados.
rogerdpack
34

Si su iframe es de otro dominio, (dominio cruzado), simplemente necesitará usar esto:

var currentUrl = document.referrer;

y - aquí tienes la url principal!

ParPar
fuente
Eso no funcionó en mi caso, ya que creo que el iFrame en sí mismo se ha generado dinámicamente o hizo algún otro truco. En cualquier caso, no obtuve la respuesta que esperaba.
Muskie
Esto debería funcionar en todos los navegadores. A menos que en los navegadores más nuevos, si envía parámetros de Sandboxing, pero dudo que este sea el caso. Esto funciona independientemente del dominio cruzado.
gcb
Si la página dentro del iframe se volvió a cargar a través de javascript (por ejemplo window.location.reload(true)), esto ya no funciona. Entonces el referente es la URL del propio iframe.
mori
20

Para páginas en el mismo dominio y subdominio diferente, puede establecer la document.domainpropiedad a través de javascript.

Tanto el marco principal como el iframe deben establecer su document.domain en algo que sea común entre ellos.

es decir, www.foo.mydomain.comy api.foo.mydomain.comcada uno podría usar uno foo.mydomain.como solo mydomain.comy ser compatible (no, no puede configurarlos a ambos com, por razones de seguridad ...)

Además, tenga en cuenta que document.domain es una calle de sentido único. Considere ejecutar las siguientes tres declaraciones en orden:

// assume we're starting at www.foo.mydomain.com
document.domain = "foo.mydomain.com" // works
document.domain = "mydomain.com" // works
document.domain = "foo.mydomain.com" // throws a security exception

Los navegadores modernos también pueden usar window.postMessage para hablar entre orígenes, pero no funcionará en IE6. https://developer.mozilla.org/en/DOM/window.postMessage

usuario409021
fuente
3
Acepte esto como la respuesta, ahora que esto es posible y que esta respuesta está apareciendo en las búsquedas de Google.
Metagrapher
17

La siguiente línea funcionará: document.location.ancestorOrigins[0]esta devuelve el nombre del dominio ancestro.

Robert-Jan Kuyper
fuente
Después de los cambios realizados en Chrome, esta es la respuesta correcta para muchos navegadores.
Dan Atkinson el
Sin embargo, no es la url completa. Solo el dominio
TheMaster
document.location.ancestorOriginsvuelve undefinedpor mí
Miguel Mota
Con respecto al soporte del navegador, específicamente, a partir de julio de 2020, ancestorOrigins aún no es compatible con Firefox debido a problemas de privacidad. Solicitud y discusión de la función Bugzilla: bugzilla.mozilla.org/show_bug.cgi?id=1085214 . Soporte del navegador: caniuse.com/#search=ancestorOrigins
colin moock
9

Intentalo:

document.referrer

Cuando cambia, se encuentra en un iframe, su host es "referente".

Benjamim William L. Nunes
fuente
2

He tenido problemas con esto. Si usa un lenguaje como php cuando su página se carga por primera vez en el iframe grab $_SERVER['HTTP_REFFERER']y configúrelo en una variable de sesión.

De esta manera, cuando la página se carga en el iframe, conoce la url principal completa y la cadena de consulta de la página que la cargó. Con la seguridad del navegador cruzado, es un poco dolor de cabeza contar con window.parent cualquier cosa si tiene diferentes dominios.

Escrituras de Hyzer
fuente
2
var url = (window.location != window.parent.location) ? document.referrer: document.location;

Descubrí que el ejemplo anterior sugería que funcionaba anteriormente cuando el script se estaba ejecutando en un iframe; sin embargo, no recuperó la URL cuando el script se ejecutó fuera de un iframe, se requirió un pequeño ajuste:

var url = (window.location != window.parent.location) ? document.referrer: document.location.href;
usuario3523340
fuente
2
Si está fuera del iframe, entonces está ejecutando el script EN el marco primario, no necesita verificar nada.
Art3mix
1

No pude obtener una solución anterior para trabajar, pero descubrí que si configuraba el iframe scr con, por ejemplo http:otherdomain.com/page.htm?from=thisdomain.com/thisfolder, podría, en el extracto de iframe, thisdomain.com/thisfolderusar el siguiente javascript:

var myString = document.location.toString();
var mySplitResult = myString.split("=");
fromString = mySplitResult[1];
Pablo
fuente
1

El problema con PHP $ _SERVER ['HTTP_REFFERER'] es que proporciona la URL de página totalmente calificada de la página que lo llevó a la página principal. Eso no es lo mismo que la página principal, en sí misma. Peor aún, a veces no hay http_referer, porque la persona escribió la url de la página principal. Entonces, si llego a su página principal desde yahoo.com, yahoo.com se convierte en http_referer, no en su página.

TARKUS
fuente
1

He encontrado en los casos en $_SERVER['HTTP_REFERER']que no funciona (te estoy mirando, Safari), $_SERVER['REDIRECT_SCRIPT_URI']ha sido una copia de seguridad útil.

Dan
fuente
0

En Chrome es posible usar location.ancestorOrigins. Devolverá todas las URL principales

Gena Moroz
fuente
0

Sé que la suya es muy antigua, pero me sorprende que nadie recomendara simplemente pasar las cookies de un dominio a otro. Como está utilizando subdominios, puede compartir cookies de un dominio base a todos los subdominios simplemente configurando cookies en la URL.basedomain.com

Luego puede compartir cualquier información que necesite a través de las cookies.

Bruce
fuente
-1

Esto funcionó para mí para acceder a la URL del iframe src.

window.document.URL
usuario1503606
fuente
-4

Obtener todas las funciones de iframe principal y HTML

var parent = $(window.frameElement).parent();
        //alert(parent+"TESTING");
        var parentElement=window.frameElement.parentElement.parentElement.parentElement.parentElement;
        var Ifram=parentElement.children;      
        var GetUframClass=Ifram[9].ownerDocument.activeElement.className;
        var Decision_URLLl=parentElement.ownerDocument.activeElement.contentDocument.URL;
Vijay Kumar
fuente
No creo que pueda ampliar esta respuesta para aquellos de nosotros que no usamos jQuery (un número creciente, debo señalar, ya que jQuery se ha vuelto cada vez más innecesario en los últimos años). Por lo menos, sugiero dejar en claro que esta respuesta depende de jQuery y el OP no mencionó jQuery en absoluto.
Carnix