JSONP

  • Por
Qué es JSONP y por qué se utiliza en el desarrollo de sitios web. Ejemplos JSONP en la librería Javascript jQuery.

El uso de APIs en el mundo del desarrollo web está cada vez más extendido y el formato JSON se ha popularizado como formato de intercambio de información. Es ligero y compatible con la mayoría de los sistemas donde lo puedas llegar a consumir.

En el mundo de la web y con respecto a la programación del lado del cliente, es habitual que queramos consultar datos que vienen de APIs REST para realizar aplicaciones enriquecidas. Esos datos pueden estar alojados en nuestro servidor o en servidores remotos, en cuyo caso podría haber algunas restricciones de seguridad. Para evitarlo puede que hayas oído hablar en alguna ocasión de JSONP. En este artículo queremos profundizar en la materia y contarte algunas diferencias entre JSON y JSONP, así como los motivos y modos de uso de JSONP.

Problemática de seguridad con JSON

Quizás alguna vez has advertido que, en ciertas ocasiones, no es posible hacer una llamada a Ajax a través de dominios distintos para traernos algún dato. Esto es una limitación en la programación web del lado del cliente y es debido a una restricción de seguridad de los navegadores.

La causante de ese problema es una política llamada "Same-origin policy", que está pensada para evitar que se carguen mediante Javascript datos potencialmente inseguros, por estar en otros servidores. Es decir, los datos que nos traemos desde Ajax conectando con nuestro propio dominio son considerados seguros, pero los que están en otros dominios de Internet no.

Esta restricción se puede evitar si el dominio con el que te conectas está configurado para aceptar conexiones desde otros dominios. Esto se consigue activando la configuración "Cross-origin resource sharing", pero también puede solucionarse, independientemente de la configuración del servidor, a través del uso de JSONP.

Cómo es JSONP

JSON y JSONP son básicamente lo mismo, un formato ligero para intercambiar datos con notación de objeto Javascript. La notación no difiere en absoluto entre JSON y JSONP, pero sí la "envoltura". En JSONP en lugar de viajar el dato a secas como en JSON, lo que viaja es una función generalmente llamada "callback". Esa función es como un Javascript, que engloba el dato que hemos solicitado. De ahí que a veces se conozca a JSONP como JSON con padding.

Nota: No comentamos mucho acerca de JSON porque ha sido motivo de diversos artículos. Para referencia puedes consultar el artículo Qué es JSON.

Por ejemplo mira el código fuente que recibes cuando accedes a esta URL:

"http://api.openbeerdatabase.com/v1/beers.json?callback=mifuncion&query=beer"

Verás que lo que recibes es algo como esto:

mifuncion({
	"datos": "del",
	"json": "con JSONP"
})

Por qué JSON no puedo accederlo y sí JSONP

Quizás te preguntes: Si hemos dicho que debido a la restricción de los navegadores "Same-origin policy" no se puede acceder a datos que residen en servidores externos. ¿Por qué puedo acceder a los datos JSONP y no a los JSON normales?

Realmente son lo mismo, solo cambia un poco de esa envoltura de la función en JSONP. ¿Cuál es la magia?

Para hacer posible el JSONP en situaciones cross-domain se usa una alternativa permitida de carga de scripts en una página. Como sabes, el navegador sí que acepta la carga de código Javascript que traigas con la etiqueta SCRIPT y el atributo src de otro dominio. Es la base de los servicios CDN.

<script src="http://example.com/otro/dominio"></script>

Debido a que eso no provoca ningún problema de seguridad, JSONP se aprovecha de ello para acceder de ese modo al recurso solicitado, inyectando ese script en la página y ejecutando su código para extraer el dato.

Nota: Fíjate que si te llegase un JSON normal no podrías ejecutarlo tal cual. El JSON es un literal de objeto y no una sentencia Javascript que sea capaz de ejecutar el navegador, por ello no podrías meterlo tal cual en una etiqueta SCRIPT de la página.

Cómo procesar un JSONP para extraer el dato

Afortunadamente nuestra librería Javascript preferida debe ser capaz de extraer ese dato por nosotros, de una manera semi-transparente. Generalmente solo tendremos que advertir que vas a recibir el dato en JSONP en lugar de JSON tradicional.

Lógicamente la forma que haremos esto depende de la construcción de tu librería. Veamos ahora algunos ejemplos de código. Verás que es bastante sencillo.

JSONP en jQuery

Para indicar a jQuery que el dato de respuesta llega en JSONP utilizamos la variable de configuración "dataType", asignando el valor "jsonp".

Este código no te requerirá muchas explicaciones si conoces el trabajo con Ajax en jQuery. Revisa el Manual de jQuery para eventuales consultas de Ajax.

$.ajax({
url: "http://api.openbeerdatabase.com/v1/beers.json",
	data: {
		query: "beer"
	},
	type: "GET",
	dataType: "jsonp",
	success: function(respuesta){
console.log("Recibes: ", respuesta);
$("<pre>").text(JSON.stringify(respuesta)).appendTo("body");
	}
});

Lo que quiero que se vea es que en la función success() el parámetro "respuesta" tiene un objeto Javascript nativo, que es el resultado de la cadena JSONP recibida convertida en su correspondiente objeto.

Con el console.log() vuelcas ese dato en la consola de Javascript. Con la etiqueta PRE creada al vuelo y el método JSON.stringify() consigo que se convierta ese objeto a un literal de cadena, con lo que puedo volcarlo como texto en la página y verlo sin necesidad de la consola. Generalmente tú en tu programa harás con tu objeto otra cosa distinta, eso ya depende de tu aplicación y el objetivo de los datos que acabas de recibir. Lo interesante aquí es que jQuery se encarga el solito de transformarte el JSONP en un objeto manipulable por código Javascript.

De momento es todo. Espero que hayas resuelto tus dudas y no sea para ti un problema acceder a cualquier API que te devuelve datos con JSONP.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

Leo

14/10/2014
Relleno
La traducción de páding sería "relleno" ¿no? entonces podríamos decir que es un JSON con relleno. Pero lo que distingue a este formato es la envoltura de la función. Podrían simplemente colocar el nombre de una variable y asignarle lo que viene del JSON ¿Por qué se ha optado por poner una función de envoltura?

sergio_razza

14/10/2014
Excelente Articulo
Claro y conciso... muy bueno!

eiximenis

15/10/2014
Re: Relleno
@Leo
Porque es la costumbre que más se ha adoptado... pero se podría perfectamente asignarlo a una variable y seguiría siendo "JSONP". :)

German

05/1/2015
Primer ejemplo
Todo muy claro. Pero en el primer ejemplo, el de la url ("http://api.openbeerdatabase.com/v1/beers.json?callback=mifuncion&query=beer"), quien devuelve el JSON envuelto en la función es el servidor??
En ese caso, JSONP debería tener una pequeña lógica en el servidor para que funcione, en ningun lado explican eso. Es correcto esto?

RAUL

22/5/2018
Duda
Hola Germán. Tengo la misma duda. No viene nada en la web. Diste con la solución? Por favor si sabes algo me lo podrías decir. Estoy harto. Me ejecuta pero me dice q no puede ejecutar la función de callback