SecurityError: Se bloqueó el acceso de un marco con origen a un marco de origen cruzado
Estoy cargando un <iframe>
en mi página HTML e intentando acceder a los elementos que contiene usando JavaScript, pero cuando intento ejecutar mi código, aparece el siguiente error:
SecurityError: se bloqueó el acceso de un marco con origen "http://www.example.com" a un marco de origen cruzado.
¿Cómo puedo acceder a los elementos del marco?
Estoy usando este código para realizar pruebas, pero es en vano:
$(document).ready(function() {
var iframeWindow = document.getElementById("my-iframe-id").contentWindow;
iframeWindow.addEventListener("load", function() {
var doc = iframe.contentDocument || iframe.contentWindow.document;
var target = doc.getElementById("my-target-id");
target.innerHTML = "Found it!";
});
});
Política del mismo origen
No puedes acceder a un <iframe>
origen diferente usando JavaScript; sería una gran falla de seguridad si pudieras 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:
protocolo :// nombre de host : puerto /...
El protocolo, el nombre de host y el puerto deben ser los mismos que los de su dominio si desea acceder a una trama.
NOTA: aunque hoy en día casi no se utiliza, se sabe que Internet Explorer no sigue estrictamente esta regla; consulte aquí para obtener más detalles.
Ejemplos
Esto es lo que sucedería al intentar acceder a las siguientes URL desdehttp://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 impide que los scripts accedan al contenido de sitios con un origen diferente, si posee ambas páginas, puede solucionar este problema usando window.postMessage
y su message
evento relativo para enviar mensajes entre las dos páginas, como este:
En tu página principal:
const frame = document.getElementById('your-frame-id'); frame.contentWindow.postMessage(/*any variable or object here*/, 'https://your-second-site.example');
El segundo argumento para
postMessage()
poder ser'*'
no indicar preferencia sobre el origen del destino. Siempre que sea posible, siempre se debe proporcionar un origen de destino, 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 === 'https://your-first-site.example') { // 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 también 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 encontré buscando en Google), por lo que, para los navegadores donde esto 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 orígenes cruzados, por lo que es muy inseguro y NUNCA debe hacerse si no sabe exactamente lo que está haciendo (por ejemplo, con fines de desarrollo) .
- Google Chrome
- Mozilla Firefox
- Safari
- Opera : igual que Chrome
- Microsoft Edge: igual que Chrome
- Valiente: igual que Chrome
- Microsoft Edge (versión antigua que no es Chromium): no es posible
- Microsoft Internet Explorer
Complementando la respuesta de Marco Bonelli: la mejor forma actual de interactuar entre marcos/iframes es utilizar window.postMessage
, compatible con todos los navegadores
Verifique la http://www.example.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 el clickJacking?
- La página malvada se ve exactamente igual a la página de la víctima.
- Luego engañó a los usuarios para que ingresaran su nombre de usuario y contraseña.
Técnicamente, el mal tiene una iframe
fuente con la página de la víctima.
<html>
<iframe src='victim-domain.example'/>
<input id="username" type="text" style="display: none;"/>
<input id="password" type="text" style="display: none;"/>
<script>
//some JS code that click jacking the user username and input from inside the iframe...
<script/>
<html>
Cómo funciona la característica de seguridad
Si desea evitar que la solicitud del servidor web se procese dentro de un iframe
complemento, agregue las opciones de marco x
Opciones de X-Frame DENEGAR
Las opciones son:
SAMEORIGIN
: permitir que solo mi propio dominio represente mi HTML dentro de un iframe.DENY
: no permitir que mi HTML se represente dentro de ningún iframeALLOW-FROM https://example.com/
: permitir que un dominio específico represente mi HTML dentro de un iframe
Este es un ejemplo de configuración de IIS:
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
La solución a la pregunta.
Si el servidor web activó la función de seguridad, puede causar un error de seguridad del lado del cliente como debería.