JSONP

Este ejemplo me decidí a escribirlo después de leer la serie de artículos publicados en el blog de José Alarcón sobre JSONP.

1- Llamadas AJAX a servidores remotos.
2- Soporte desde ASP.NET AJAX 4.0
3- Cuestiones de seguridad y ASP.NET rompiendo la compatibilidad en 3.5

Requisitos: Crear un input tipo text con auto completamiento de las ciudades de España. Para esto usaré geonames.org, que es un servicio gratuito que nos permite obtener geo-localizaciones a partir de determinados parámetros y cuya documentación la encontramos en su sitio:

http://www.geonames.org/export/geonames-search.html

Como JQuery está de moda… y este soporta JSONP, voy a usar el pluging que existe para el auto-completamiento y que lo pueden encontrar en http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/.

Con esto creo que completo todo lo que necesito así que vamos con el código. Empezamos con lo de siempre, indicando cual es el control al cual le vamos a aplicar el “autocomplete” y cuál será la fuente de datos.

$(«#txt_city»).autocomplete(«http://ws.geonames.org/searchJSON»,

Vamos a realizar un pequeño truco, porque al final el objetivo de este artículo es justificar el uso de JSONP, así empezamos indicando los parámetros del “autocomplete” esperando como respuesta un JSON.

dataType: ‘json’,

Seguimos especificando una función que realizará un Parse de los datos que me retorna geonames, para poder entregárselos al autocomplete de la manera que él lo entiende.

parse: function(data)
{
      var rows = new Array();
      data = data.geonames;

      for(var i=0; i<data.length; i++)
      {
         rows[i] = 
         {
           
data:data[i],
            value:data[i].name,
            result:data[i].name
         };
      }               

      return rows;
},

Nada importante hasta aquí.. una función que convierte el resultado en un arreglo que contiene el dato, el valor de cada elemento y el resultado. Seguimos con la función que se llamará a la hora de mostrar el autocomplete e indicamos que solo mostraremos el nombre de la ciudad.

formatItem: function(row, i, n)
{
      return row.name;
},

Continuamos incluyendo los parámetros necesarios para realizar la búsqueda (País, indicar que no deseo lugares geográficos, etc.) Todos estos parámetros están bien documentados en el sitio de geoname.

extraParams:
{
      q: »,
      limit: »,
      country: ‘ES’,
      featureClass: ‘P’,
      maxRows: 50,
      name_startsWith: function ()
      {
        return $(«#txt_city»).val()
      }
},

Luego decimos que nuestro autocomplete espera un máximo de 50 elementos y listo.

max: 50

Con definir nuestro html con un input cuyo ID=”txt_city”, tendremos nuestro autocomplete, así que ejecutamos….

OPS!!! Acceso denegado… Este error proviene precisamente por la imposibilidad de hacer un pedido a un dominio que no es el nuestro, estamos intentando hacer un Cross Site Scripting.

¿Cómo lo resolvemos? Un buen comienzo es estudiando la serie de artículos propuestos al inicio de este post, pero para nuestro ejemplo, JQuery lo hace tan simple como ya nos tiene acostumbrado. Cambiamos el tipo de dato que espera el autocomplete a jsonp:

dataType: ‘jsonp’,

y….

We are happy 🙂

Aquí les dejo un enlace al ejemplo completo, que no es más que una simple página html ya que no usamos ASP.NET para nada, es código html duro y puro.

Ejemplo

2 comentarios sobre “JSONP”

  1. para que sirve o que es el parámetro parse:?
    es del plugin autocomplete?, he visto la dcumentacion pero no hay ese parametro o no lo se, no entiendo :S
    o es que cada quien puede especificar una funcion en ese paso? para acomodar los datos si se necesitara?
    Por favor aclarme el tema
    Gracias!

  2. Hola keo…

    El parse, es parte del autocomplete, y no está  documentado, por eso no la ves. Pero es tal como te lo has planteado, cada uno escribe esa función con el fin de acomodar los datos en caso de ser necesitarlo..

    Si miras la llamada ajax que realiza el autocomplete verás este código:

    $.ajax({
      // …
      success: function(data) {
         var parsed = 
             options.parse && options.parse(data) 
             || parse(data);
      // ….
    });

    Lo que hace el autocomplete acá, es que si la llamada ajax fue correcta, entonces pregunta si hemos definido mediante el parametro options una función que realiza el parse, de ser así, esta es llamada pasando el resultado y sino, entonces llama a una función interna llamada parse que trae el autocomplete.

    El autocomplete, documenta la opcción formatResult para que nosotros acomodemos los datos, lo que pasa es que esta función es llamada desde el parse interno del pluging el cual separa cada fila por «n» y esto no siempre tiene por qué ser así… como ves en geoname ya yo obtengo un array..

    Definiendo una función en Parse como parte de las opciones, te permite tener un mayor control de como harás el format de los datos..

    Espero haberte ayudado, salu2

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *