Buscar..
Introducción
Los navegadores web utilizan la política del mismo origen para evitar que los scripts puedan acceder al contenido remoto si la dirección remota no tiene el mismo origen que el script. Esto evita que los scripts maliciosos realicen solicitudes a otros sitios web para obtener datos confidenciales.
El origen de dos direcciones se considera el mismo si ambas URL tienen el mismo protocolo , nombre de host y puerto .
Maneras de eludir la política del mismo origen
En lo que respecta a los motores de JavaScript del lado del cliente (los que se ejecutan dentro de un navegador), no hay una solución sencilla disponible para solicitar contenido de fuentes que no sean el dominio actual. (Por cierto, esta limitación no existe en herramientas de servidor JavaScript como Node JS).
Sin embargo, es posible (en algunas situaciones) recuperar datos de otras fuentes utilizando los siguientes métodos. Tenga en cuenta que algunos de ellos pueden presentar hacks o soluciones alternativas en lugar de soluciones en las que debe confiar el sistema de producción.
Método 1: CORS
Hoy en día, la mayoría de las API públicas permiten a los desarrolladores enviar datos de manera bidireccional entre el cliente y el servidor al habilitar una función llamada CORS (Intercambio de recursos entre orígenes). El navegador comprobará si un determinado encabezado HTTP ( Access-Control-Allow-Origin
) está configurado y si el dominio del sitio solicitante se encuentra en el valor del encabezado. Si es así, entonces el navegador permitirá establecer conexiones AJAX.
Sin embargo, como los desarrolladores no pueden cambiar los encabezados de respuesta de otros servidores, no siempre se puede confiar en este método.
Método 2: JSONP
JSON con la adición de P se suele culpar por ser una solución alternativa. No es el método más sencillo, pero aún así hace el trabajo. Este método aprovecha el hecho de que los archivos de script se pueden cargar desde cualquier dominio. Aún así, es crucial mencionar que solicitar código JavaScript de fuentes externas siempre es un riesgo potencial de seguridad y esto generalmente debe evitarse si hay una mejor solución disponible.
Los datos solicitados utilizando JSONP son típicamente JSON , que se ajustan a la sintaxis utilizada para la definición de objetos en JavaScript, lo que hace que este método de transporte sea muy simple. Una forma común de permitir que los sitios web utilicen los datos externos obtenidos a través de JSONP es envolverlos dentro de una función de devolución de llamada, que se establece mediante un parámetro GET
en la URL. Una vez que se cargue el archivo de script externo, se llamará a la función con los datos como su primer parámetro.
<script>
function myfunc(obj){
console.log(obj.example_field);
}
</script>
<script src="http://example.com/api/endpoint.js?callback=myfunc"></script>
El contenido de http://example.com/api/endpoint.js?callback=myfunc
puede verse así:
myfunc({"example_field":true})
La función siempre debe definirse primero, de lo contrario no se definirá cuando se cargue el script externo.
Comunicación segura de origen cruzado con mensajes.
El método window.postMessage()
junto con su manejador de eventos relativos window.onmessage
puede usar de manera segura para habilitar la comunicación de origen cruzado.
Se puede llamar al método postMessage()
de la window
destino para enviar un mensaje a otra window
, que podrá interceptarlo con su controlador de eventos onmessage
, elaborarlo y, si es necesario, enviar una respuesta a la ventana del remitente usando postMessage()
nuevo.
Ejemplo de ventana comunicándose con un marco de niños.
Contenido de
http://main-site.com/index.html
:<!-- ... --> <iframe id="frame-id" src="http://other-site.com/index.html"></iframe> <script src="main_site_script.js"></script> <!-- ... -->
Contenido de
http://other-site.com/index.html
:<!-- ... --> <script src="other_site_script.js"></src> <!-- ... -->
Contenido de
main_site_script.js
:// Get the <iframe>'s window var frameWindow = document.getElementById('frame-id').contentWindow; // Add a listener for a response window.addEventListener('message', function(evt) { // IMPORTANT: Check the origin of the data! if (event.origin.indexOf('http://other-site.com') == 0) { // Check the response console.log(evt.data); /* ... */ } }); // Send a message to the frame's window frameWindow.postMessage(/* any obj or var */, '*');
Contenido de
other_site_script.js
:window.addEventListener('message', function(evt) { // IMPORTANT: Check the origin of the data! if (event.origin.indexOf('http://main-site.com') == 0) { // Read and elaborate the received data console.log(evt.data); /* ... */ // Send a response back to the main window window.parent.postMessage(/* any obj or var */, '*'); } });