Política del mismo origen
No puede acceder a un <iframe>
origen diferente usando JavaScript, sería un gran defecto de seguridad si pudiera hacerlo. Para la política del mismo origen, los navegadores bloquean los scripts que intentan acceder a un marco con un origen diferente .
El origen se considera diferente si no se mantiene al menos una de las siguientes partes de la dirección:
<protocol>://<hostname>:<port>/...
El protocolo , el nombre de host y el puerto deben ser los mismos de su dominio, si desea acceder a un marco.
NOTA: se sabe que Internet Explorer no sigue estrictamente esta regla, consulte aquí para más detalles.
Ejemplos
Esto es lo que sucedería al intentar acceder a las siguientes URL desde http://www.example.com/home/index.html
URL RESULT
http://www.example.com/home/other.html -> Success
http://www.example.com/dir/inner/another.php -> Success
http://www.example.com:80 -> Success (default port for HTTP)
http://www.example.com:2251 -> Failure: different port
http://data.example.com/dir/other.html -> Failure: different hostname
https://www.example.com/home/index.html:80 -> Failure: different protocol
ftp://www.example.com:21 -> Failure: different protocol & port
https://google.com/search?q=james+bond -> Failure: different protocol, port & hostname
Solución alterna
Aunque la política del mismo origen bloquea el acceso de los scripts al contenido de sitios con un origen diferente, si posee ambas páginas, puede solucionar este problema utilizando window.postMessage
y su message
evento relativo para enviar mensajes entre las dos páginas, de esta manera:
En tu página principal:
let frame = document.getElementById('your-frame-id');
frame.contentWindow.postMessage(/*any variable or object here*/, 'http://your-second-site.com');
El segundo argumento postMessage()
puede ser '*'
indicar que no hay preferencia sobre el origen del destino. Siempre se debe proporcionar un origen de destino cuando sea posible, para evitar revelar los datos que envía a cualquier otro sitio.
En su <iframe>
(contenido en la página principal):
window.addEventListener('message', event => {
// IMPORTANT: check the origin of the data!
if (event.origin.startsWith('http://your-first-site.com')) {
// The data was sent from your site.
// Data sent with postMessage is stored in event.data:
console.log(event.data);
} else {
// The data was NOT sent from your site!
// Be careful! Do not use it. This else branch is
// here just for clarity, you usually shouldn't need it.
return;
}
});
Este método se puede aplicar en ambas direcciones , creando un oyente en la página principal y recibiendo respuestas del marco. La misma lógica también se puede implementar en ventanas emergentes y, básicamente, en cualquier ventana nueva generada por la página principal (por ejemplo, usando window.open()
), sin ninguna diferencia.
Deshabilitar la política del mismo origen en su navegador
Ya hay algunas buenas respuestas sobre este tema (las acabo de buscar en Google), por lo que, para los navegadores donde sea posible, vincularé la respuesta relativa. Sin embargo, recuerde que deshabilitar la política del mismo origen solo afectará a su navegador . Además, ejecutar un navegador con la configuración de seguridad del mismo origen deshabilitada otorga a cualquier sitio web acceso a recursos de origen cruzado, por lo que es muy inseguro y NUNCA debe hacerse si no sabe exactamente lo que está haciendo (por ejemplo, con fines de desarrollo) .
Access-Control-Allow-Origin
no se aplica a iFrames, solo a XHR, Fonts, WebGL ycanvas.drawImage
. Creo quepostMessage
es la única opción.iframe.src
, y si el sitio es diferente del nombre de host de su dominio, entonces no puede acceder a ese marco.~
devuelve el complemento de 2 del número, por lo que sen
convierte-n-1
, lo que significa que solo-1
se convertirá0
(lo que se interpreta comofalse
), y cualquier otro valor pasará la prueba. IE0 = -(-1)-1
, no-(-1+1)
.location.ancestorOrigins[0]
es la ubicación del marco primario. Si su marco se está ejecutando dentro de otro sitio y lo verifica utilizandoevent.origin.indexOf(location.ancestorOrigins[0])
, está verificando si el origen del evento contiene la dirección del marco del padre, que siempre serátrue
, por lo tanto, está permitiendo que cualquier padre con cualquier origen acceda a su marco, y esto obviamente no es algo que quieras hacer. Además, tambiéndocument.referrer
es una mala práctica, como ya expliqué en los comentarios anteriores.Complementando la respuesta de Marco Bonelli: está utilizando la mejor forma actual de interactuar entre marcos / iframes
window.postMessage
, compatible con todos los navegadoresfuente
window.postMessage
funciona solo duplicaría la respuesta aceptada a la que ya me refiero. Además, el valor esencial que agrega mi respuesta es exactamente el de hacer referencia a documentación externa.Verifique la
http://www.<domain>.com
configuración del servidor web del dominio.X-Frame-Options
Es una característica de seguridad diseñada para evitar ataques de clickJacking,¿Cómo funciona clickjacking?
Técnicamente el mal tiene una
iframe
fuente con la página de la víctima.Cómo funciona la característica de seguridad
Si desea evitar que la solicitud del servidor web se procese dentro de un
iframe
agregar las opciones x-frame-Las opciones son:
Este es el ejemplo de configuración de IIS:
La solución a la pregunta.
Si el servidor web activó la función de seguridad, puede causar un SecurityError del lado del cliente como debería.
fuente
Para mí, quería implementar un protocolo de enlace bidireccional, lo que significa:
- la ventana principal se cargará más rápido que el iframe
- el iframe debería hablar con la ventana principal tan pronto como esté listo
- el padre está listo para recibir el mensaje del iframe y reproducirlo
este código se usa para establecer la etiqueta blanca en el iframe usando el código [propiedad personalizada CSS]
:
iframe
padre
naturalmente, puede limitar los orígenes y el texto, este es un código fácil de trabajar.
Este examen me pareció útil:
[Mensajes entre dominios con postMessage]
fuente
Me gustaría agregar la configuración específica de Java Spring que pueda afectar esto.
En el sitio web o la aplicación Gateway hay una configuración contentSecurityPolicy
en Spring puedes encontrar la implementación de la subclase WebSecurityConfigurerAdapter
...
El navegador se bloqueará si no ha definido un contenido externo seguro aquí.
fuente
Si tiene control sobre el contenido del iframe, es decir, si simplemente se carga en una configuración de origen cruzado como en Amazon Mechanical Turk, puede sortear este problema con el
<body onload='my_func(my_arg)'>
atributo para el html interno.Por ejemplo, para el html interno, use el
this
parámetro html (sí,this
está definido y se refiere a la ventana principal del elemento del cuerpo interno):<body onload='changeForm(this)'>
En el html interno:
fuente
chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security
fuente