http://bob.ippoli.to/archives/2005/12/05/remote-json-jsonp/
http://www.json-p.org/
http://johnnywey.com/2012/05/20/jsonp-how-does-it-work/
JSONP (JSON con Padding) es una técnica mediante la que podemos obtener y tratar JSON desde otros dominios (desde javascript).
Con esta tecnica/hack obtenemos el JSON pasado como parametro a una funcion que se ejecuta en el cliente
-
Si desde la pagina
MYsite.com
ejecuto$.ajax({ url: 'http://www.ANOTHERsite.com/datos.json', success: function(data) { console.log(data) } });
el navegador (Chrome) me devuelve algo asi:
Refused to connect to 'http://www.anothersite.com/datos.json' because it violates the following Content Security Policy directive...
debido a la "Same-origin policy" del objeto
XMLHttpRequest
-
Sin embargo si hacemos esto
<script type="text/javascript" src="http://www.ANOTHERsite.com/datos.json"></script>
si que podriamos obtener el JSON
{ "api_key": "224Wrf2asfSDfcea23reSDfqW", "status": "good", "name": "wikipedia", "date": "27-09-1995" }
pero no podriamos acceder al JSON obtenido ya que no queda almacenado en niguna variable
-
La solucion para poder tratar este JSON es preparar el servidor para que devuelva el JSON envuelto en la llamada a una función
handleMyJSONResponse ({ "api_key": "224Wrf2asfSDfcea23reSDfqW", "status": "good", "name": "wikipedia", "date": "27-09-1995" });
Asi, si definimos en el cliente una funcion global
handleMyJSONResponse
preparada para recibir un JSON como parametro, ya podriamos recibir y tratar estos datos desde JS.window.handleMyJSONResponse = function (datosJSON) { console.log (datosJSON); };
-
Por convención, el nombre de la función callback se especifica en un parámetro (jsonp, callback o cualquier otro) de la URL que hace la peticion al servidor.
<script type="text/javascript" src="http://www.ANOTHERsite.com/datos.json?callback=handleMyJSONResponse"></script>
-
Con código nativo
jsFiddle: Ejemplos JSONP con JS nativo
window.do_things = function (data) { console.log ( "do_things : %o", data.responseData.results ); } function loadScript (id, src, callback) { // Crear elemento var script = document.createElement("script"); // Atributos del script script.setAttribute("type", "text/javascript"); script.setAttribute("src", src + "&callback=" + callback); script.setAttribute("id", id); // Insertar script en la cabecera document.getElementsByTagName("head")[0].appendChild(script); } loadScript ("my_script_tag_id", "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=casas+alquiler", "do_things");
-
Con jQuery
JQuery se encarga (de forma transparente al developer) de darle un nombre a la funcion callback, pasarla en la peticion, crearla globalmente en el cliente y se encarga también de añadir y eliminar el tag script utilizado internamente
jsFiddle: Ejemplos JSONP jQuery
jsFiddle: Ejemplo JSONP jQuery (Google Search Form)```javascript
$.getJSON( 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=casas+alquiler&callback=?', function( googleResults) { console.log ( "$.getJSON : %o", googleResults.responseData.results ); } );
$.ajax({ url: "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=casas+alquiler", dataType: "jsonp", success: function( response ) { console.log ( "$.ajax minimal : %o", response.responseData.results ); } });
La mayoria de las API's publicas vienen ya preparadas para devolver JSONP:
https://api-notebook.anypoint.mulesoft.com/
-
https://api.instagram.com/v1/tags/coffee/media/recent?access_token=fb2e77d.47a0479900504cb3ab4a1f626d174d2d&callback=callbackFunction
-
https://api.github.com/?callback=foo
-
https://www.flickr.com/services/rest/?method=flickr.test.echo&format=json&api_key=929033444e3a0d9a3859195d56d36552
-
https://api.linkedin.com/v1/people/~:(id)?callback=firstNameResponse&error-callback=firstNameError
-
https://api.soundcloud.com/tracks.json?client_id=YOUR_CLIENT_ID&callback=processTracks