¿Cómo enviar JSON en lugar de una cadena de consulta con $ .ajax?


172

¿Alguien puede explicar de una manera fácil cómo hacer que jQuery envíe JSON real en lugar de una cadena de consulta?

$.ajax({
    url      : url,
    dataType : 'json', // I was pretty sure this would do the trick
    data     : data,
    type     : 'POST',
    complete : callback // etc
});

De hecho, esto convertirá su JSON cuidadosamente preparado en una cadena de consulta. Una de las cosas molestas es que cualquiera array: []en su objeto se convertirá array[]: [], probablemente debido a las limitaciones de la picadura de la consulta.


77
El dataTypeno tiene relación con cómo se envían los datos. Simplemente especifica cuál es el tipo de datos que espera que devuelva la llamada. Si desea indicar al servidor cuál es el tipo de datos que está especificando en la datapropiedad que necesita para establecer una contentTypepropiedad similar acontentType: "application/json"
Nope

Gracias por aclararlo. Pero en ese caso, ¿por qué necesito especificar el tipo de respuesta del lado del cliente si el servidor proporciona un encabezado de tipo contenido en la respuesta?
Redsandro

2
No tiene que especificarlo, por defecto jQuery intentará hacer una suposición inteligente basada en el tipo MIME de la respuesta. Sin embargo, al especificarlo, le está diciendo a jQuery explícitamente qué tipo espera del servidor y jQuery intentará convertir la respuesta a un objeto de ese tipo. No especificarlo y dejar que jQuery adivine puede hacer que jQuery convierta la respuesta a un formato inesperado, a pesar de que envió JSON desde el servidor. Consulte la documentación para obtener más detalles sobre el tipo de datos: api.jquery.com/jQuery.ajax
No,

Respuestas:


256

Debe usarlo JSON.stringifypara serializar primero su objeto en JSON y luego especificarlo contentTypepara que su servidor comprenda que es JSON. Esto debería funcionar:

$.ajax({
    url: url,
    type: "POST",
    data: JSON.stringify(data),
    contentType: "application/json",
    complete: callback
});

Tenga en cuenta que el JSONobjeto está disponible de forma nativa en navegadores que admiten JavaScript 1.7 / ECMAScript 5 o posterior. Si necesita soporte heredado, puede usar json2 .


14
Esto no funcionará, te estás perdiendo contentType: 'application/json'.
Ohgodwhy

@ Ohhodwhy Oh, sí. Eso fue un poco demasiado rápido;)
mekwall

1
Gracias. Pensé que dataType se encargó de esto, pero lo entendí al revés. ¿Alguna idea sobre cómo especificar el juego de caracteres en el tipo de contenido como lo hizo Bergi en la otra respuesta?
Redsandro

55
@Redsandro Eso no debería ser necesario. De acuerdo con los documentos de jQuery:POST data will always be transmitted to the server using UTF-8 charset, per the W3C XMLHTTPRequest standard
mekwall

1
@ shorif2000 mejor tarde que nunca ... el problema es que en $_POSTphp solo puedes ver application/x-www-form-urlencoded, si quieres leer los datos de json debes hacerlo file_get_contents("php://input")y quizás luego unjson_decode()
santiago arizti

28

No, la dataTypeopción es analizar los datos recibidos.

Para publicar JSON, tendrá que encadenarlo usted mismo a través de JSON.stringifyy configurar la processDataopción en false.

$.ajax({
    url: url,
    type: "POST",
    data: JSON.stringify(data),
    processData: false,
    contentType: "application/json; charset=UTF-8",
    complete: callback
});

Tenga en cuenta que no todos los navegadores son compatibles con el JSONobjeto, y aunque jQuery sí lo tiene .parseJSON, no tiene un stringifier incluido; Necesitarás otra biblioteca de polyfill.


44
Ajuste processDataa falseno es necesaria, ya que JSON.stringifyya se devuelve una cadena.
mekwall

@MarcusEkwall: Afaik todavía sería encodeURIComponenteditado, ¿no?
Bergi

OK, puede que no sea necesario, pero ¿realmente crees que haría que la solicitud fallara?
Bergi

No debería hacerlo fallar, considerando que ya es una cadena.
Kevin B

1
@Redsandro: Sí, está haciendo una "suposición inteligente". Sin embargo, la razón del parámetro no es (solo) que las personas quieran hacerlo estricto, sino más bien que no establecen tipos MIME apropiados en sus respuestas del servidor.
Bergi

5

Si bien sé que muchas arquitecturas como ASP.NET MVC tienen una funcionalidad incorporada para manejar JSON.stringify como contentType, mi situación es un poco diferente, por lo que tal vez esto pueda ayudar a alguien en el futuro. ¡Sé que me habría ahorrado horas!

Dado que mis solicitudes http están siendo manejadas por una API CGI de IBM (entorno AS400) en un subdominio diferente, estas solicitudes son de origen cruzado, de ahí el jsonp. De hecho, envío mi ajax a través de objetos de JavaScript. Aquí hay un ejemplo de mi ajax POST:

 var data = {USER : localProfile,  
        INSTANCE : "HTHACKNEY",  
        PAGE : $('select[name="PAGE"]').val(), 
        TITLE : $("input[name='TITLE']").val(), 
        HTML : html,
        STARTDATE : $("input[name='STARTDATE']").val(), 
        ENDDATE : $("input[name='ENDDATE']").val(),
        ARCHIVE : $("input[name='ARCHIVE']").val(), 
        ACTIVE : $("input[name='ACTIVE']").val(), 
        URGENT : $("input[name='URGENT']").val(), 
        AUTHLST :  authStr};
        //console.log(data);
       $.ajax({
            type: "POST",
           url:   "http://www.domian.com/webservicepgm?callback=?",
           data:  data,
           dataType:'jsonp'
       }).
       done(function(data){
         //handle data.WHATEVER
       });

2
¡Gracias por agregar más conocimiento a esta pregunta! La respuesta satisfactoria ya se había dado, pero yo voté por la suya.
Redsandro

1

Si envía esto de vuelta a asp.net y necesita los datos en request.form [], deberá configurar el tipo de contenido en "application / x-www-form-urlencoded; charset = utf-8"

Publicación original aquí

En segundo lugar, elimine el Datatype, si no espera una devolución, la POST esperará unos 4 minutos antes de fallar. Ver aquí

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.