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 */, '*');
         }
     });
    


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow