Comunicación entre dominios mediante JSONP

La política de mismo origen es un mecanismo de seguridad implementado por los navegadores que impide que scripts de diferentes orígenes lean o modifiquen recursos de otros dominios sin autorización explícita. Por ejemplo, un script ubicado en a.com no puede utilizar ajax para obtener datos de b.com debido a esta restricción.

Se considera que dos URLs tienen el mismo origen cuando comparten idénticamente el protocolo (http/https), el nombre de dominio y el número de puerto.

Elementos no afectados por esta política:

  • Los enlaces, redirecciones y envíos de formularios pueden ejecutarse sin restricciones entre dominios distintos.
  • La carga de recursos desde otros dominios está permitida, aunque JavaScript no puede acceder al contenido de dichos recursos. Esto aplica para etiquetas como <script src="...">, <img>, <link> e <iframe>.

La técnica JSONP aprovecha precisamente esta excepción: el atributo src de la etiqueta script no está sujeto a las restricciones de cross-origin, por lo que permite recuperar datos de otros dominios.

Funcionamiento de JSONP:

(Ejemplo: página en a.com/consulta.html necesita obtener datos del archivo b.com/servicio.php) Desde a.com/consulta.html se define una función de callback denominada datosRecibidos, se crea dinámicamente un elemento <script> y se configura su atributo src hacia el servidor remoto, incluyendo un parámetro calblack con el nombre de la función. La petición queda construida así: http://b.com/main.js?callback=datosRecibidos. El servidor en jsonp.php invoca la función datosRecibidos pasándole los datos en formato JSON como argumento.

Ejemplo práctico: URL de destino: http://www.ejemplo.com/api/datos?callback=procesarInformacionDatos JSON esperados: ["usuario1","usuario2"] Respuesta real enviada al navegador: procesarInformacion(["usuario1","usuario2"])

<?php
header('Content-type: application/json');
//Recuperar el nombre de la función callback
$nombreCallback = filter_input(INPUT_GET, 'cb', FILTER_SANITIZE_STRING);
//Datos JSON a enviar
$informacion = '["usuario1","usuario2"]';
//Devolver datos en formato JSONP
echo $nombreCallback . "(" . $informacion . ")";
?>

//Página del cliente
//<div id="contenedorResultados"></div>
<script type="text/javascript">
function procesarInformacion(respuesta, nombreMetodo)
    {
        var salida = ''; for(var i = 0; i &lt; respuesta.length; i++) { salida += '- ' + respuesta\[i\] + '
'; } salida += '';
        document.getElementById('contenedorResultados').innerHTML = salida;
    }
</script>
<script type="text/javascript" src="http://www.ejemplo.com/api/datos?cb=procesarInformacion"></script>

Implementar JSONP presenta limitaciones importantes:

  1. Cualquier sitio web puede solicitar y obtener los datos del servidor remoto, lo cual representa un riesgo de seguridad considerable. Es necesario establecer mecanismos de autenticación mediante tokens entre las partes involucradas.
  2. Únicamente soporta el método GET, no es posible utilizar POST para el envío de información.
  3. El servidor puede devolver código malicioso que se ejecutará en el navegador, modificando el contenido de la página. Se recomienda implementar sanitización de cadenas para mitigar este problema.

Etiquetas: JavaScript JSONP seguridad-web CORS desarrollo-web

Publicado el 7-28 15:46