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

Al fin en Geeks

Hola,

Mi nombre es Omar del Valle Rodríguez, trabajo con NET desde el año 2000 cuando toda esta maravillosa tecnología era solo un programa Beta. Actualmente soy MCP, MCTS y MCPD Enterprise en NET 3.5. Tengo mi propio blog en www.odelvalle.com pero pertenecer a esta gran comunidad ha sido siempre un sueño.

Espero no desperdiciar la oportunidad que ahora me dan de hacerlo realidad, y poder aportar algo de lo que tanto he aprendido siguiendo muchos de los blogs que aquí existen.

Unas gracias especiales a Toni, y también a todo el grupo de chicos que diariamente hace posible que Second Nug siga adelante. Gracias a ellos he podido estar y sentirme mucho más cerca de la comunidad.

Hasta muy pronto…
Omar