Muy buenas!
Una de las preguntas que mucha gente se formula cuando empieza a hacer cosillas con ajax y jQuery es ¿Como enviar datos codificados en JSON usando POST?
La verdad es que es muy sencillo, aunque jQuery no proporciona ninguna función por defecto que haga esto. Vamos a ver tres aproximaciones, las dos primeras incorrectas pero que nos acercarán para llegar al final a la una forma correcta de hacerlo.
Aproximación 1: Usando $.post
jQuery tiene una función específica para enviar datos usando post, llamada $.post. Así podriamos pensar que el siguiente método funcionaria:
function JsonPost(data, url, handler)
{
$.post(url, data, handler);
}
Y luego podríamos llamarlo de la siguiente manera:
// Envia un objeto con propiedades Col y Row a /Map/ViewPort y
// llama a fillMap con el resultado devuelto
JsonPost({ Col: c, Row: r}, "/Map/Viewport", function(data) {
fillMap(data);
});
Pero eso no realiza una petición JSON. Si usamos, p.ej. Firebug para analizar la petición vemos que lo que se envía al controlador es:
Si os fijáis los datos no están codificados en JSON, sinó en el formato “estándard” (param=value¶m=value&…)
Si se lee la documentación de $.post() se ve que acepta un último parámetro datatype, así que podríamos pensar que poniendo dicho parámetro a “json” funcionará, pero no. El parámetro “datatype” indica el tipo de datos esperado de vuelta, no el que se envia.
Resumiendo: $.post() siempre envía los datos en el formato tradicional.
Aproximación 2: Usando $.post() y convertir los datos a Json
De acuerdo, hemos visto que $.post() nos transforma nuestro objeto javascript en la cadena tradicional de param=value¶m=value&… Pero si a $.post() se le pasa una cadena la manda tal cual, por lo que si transformamos el objeto javascript a una cadena JSON parece que todo funcionará.
Para transformar un objeto javascript a notación JSON podemos usar el plugin jQuery-Json. Puede haber otros plugins por ahí, pero uséis el que uséis, aseguraros que soporta native json. Native json es una funcionalidad que los nuevos navegadores traen y que se basa en un método llamado JSON.stringify que transforma el objeto pasado a una cadena json. Evidentemente siempre será mucho más rápido si el propio navegador puede hacer esto de forma nativa que si es código javascript que construye la cadena. El plugin jQuery-json usa JSON.stringify si está disponible y sólo en caso de que no exista usa código javascript.
Así pues podríamos modificar nuestra JsonPost para que quede como:
function JsonPost(data, url, handler)
{
$.post(url,$.toJSON(data), handler);
}
El método $.toJSON es el método proporcionado por el plugin. Ahora sí que estamos usando JSON para enviar los datos:
Ok. Un parentesis: Recordad que MVC2 no tiene soporte directo para realizar binding de datos enviados en JSON. Aunque es muy fácil crearse un Value Provider propio que de soporte a JSON en MVC2. Y recordad que MVC3 ya viene con el soporte por defecto de JSON.
Bien, si usáis un value provider para JSON que os hayais encontrado por “ahí afuera” lo más probable es que no os funcione, es decir que en el controlador no recibáis los datos. Por que? Pues por lo que está marcado en rojo en la imagen antrior: aunque estamos enviando los datos en formato json, el content-type no es correcto. El content-type de JSON es application/json y este es el content-type que suelen mirar los value providers de JSON.
Aproximación 3: Usando $.ajax()
Bien, ya que $.post() no permite especificar el content-type, la tercera y última aproximación es usar $.ajax(), que es la función más personalizable que tiene jQuery para hacer peticiones ajax.
De hecho básicamente lo único que tenemos que cambiar respecto la aproximación anterior es el content-type:
function JsonPost(data, url, handler)
{
$.ajax(
{
url: url,
type: "POST",
success: handler,
data: $.toJSON(data),
contentType: "application/json"
});
}
Y lo que nos muestra Firebug de la petición:
Fijaos que ahora el propio Firebug reconoce que la petición es en JSON y me muestra los datos en JSON.
Espero que os sea útil!
Un saludo!
Cómo en el Firebug o por URL podria enviar formato JSON para que se me ejecute con una action que tengo implementado en symfony, sin tener presentacion o interfaz de usuario?????. Espero respuestas