Trick: Enviar datos en JSON usando POST

 ·  ☕ 4 min  ·  ✍️ eiximenis

    Nota: Este post ha sido importado de mi blog de geeks.ms. Es posible que algo no se vea del todo "correctamente". En cualquier caso puedes acceder a la versión original aquí

    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:

    image

    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:

    image

    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:

    image

    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!

    Si quieres, puedes invitarme a un café xD

    eiximenis
    ESCRITO POR
    eiximenis
    Compulsive Developer