Comment envoyer JSON au lieu d'une chaîne de requête avec $ .ajax?


172

Quelqu'un peut-il expliquer de manière simple comment faire en sorte que jQuery envoie du JSON réel au lieu d'une chaîne de requête?

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

Cela convertira en fait votre JSON soigneusement préparé en une chaîne de requête. L'une des choses ennuyeuses est que tout élément array: []de votre objet sera converti en array[]: [], probablement à cause des limitations de la requête.


7
Le dataTypen'a aucune incidence sur la manière dont les données sont envoyées. Il spécifie simplement le type de données que vous attendez d'être renvoyé par l'appel. Si vous souhaitez indiquer au serveur le type de données que vous spécifiez dans la datapropriété, vous devez définir la contentTypepropriété de la même manière quecontentType: "application/json"
Non

Merci de clarifier. Mais dans ce cas, pourquoi dois-je spécifier le type de réponse côté client si le serveur fournit un en-tête de type de contenu dans la réponse?
Redsandro

2
Vous n'êtes pas obligé de le spécifier, par défaut jQuery essaiera de faire une estimation intelligente basée sur le type MIME de la réponse. Cependant, en le spécifiant, vous indiquez explicitement à jQuery le type que vous attendez du serveur et jQuery tentera de convertir la réponse en un objet de ce type. Ne pas le spécifier et laisser jQuery faire une estimation peut entraîner la conversion de la réponse par jQuery dans un format inattendu, même si vous avez envoyé JSON depuis le serveur. Consultez la documentation pour plus de détails sur le type de données: api.jquery.com/jQuery.ajax
Nope

Réponses:


256

Vous devez d' JSON.stringifyabord sérialiser votre objet en JSON, puis spécifier le contentTypeafin que votre serveur comprenne qu'il s'agit de JSON. Cela devrait faire l'affaire:

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

Notez que l' JSONobjet est disponible nativement dans les navigateurs prenant en charge JavaScript 1.7 / ECMAScript 5 ou version ultérieure. Si vous avez besoin d'un support hérité, vous pouvez utiliser json2 .


14
Cela ne fonctionnera pas, vous manquez contentType: 'application/json'.
Ohgodwhy

@Ohgodwhy Oh ouais. Cela est allé un peu trop vite;)
mekwall

1
Merci. Je pensais que dataType s'occupait de cela, mais je l'ai compris à l'envers. Des réflexions sur la spécification du jeu de caractères dans le type de contenu comme Bergi l'a fait dans l'autre réponse?
Redsandro

5
@Redsandro Cela ne devrait pas être nécessaire. Selon les documents jQuery:POST data will always be transmitted to the server using UTF-8 charset, per the W3C XMLHTTPRequest standard
mekwall

1
@ shorif2000 mieux vaut tard que jamais ... le problème est qu'en $_POSTphp, vous ne pouvez que voir application/x-www-form-urlencoded, si vous voulez lire des données json, vous devez le faire file_get_contents("php://input")et peut-être alors unjson_decode()
santiago arizti

28

Non, l' dataTypeoption consiste à analyser les données reçues.

Pour publier JSON, vous devrez le stringify vous-même via JSON.stringifyet définir l' processDataoption sur false.

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

Notez que tous les navigateurs ne prennent pas en charge l' JSONobjet, et bien que jQuery l'ait fait .parseJSON, aucun stringifier n'est inclus; vous aurez besoin d'une autre bibliothèque polyfill.


4
Le réglage processDatasur falsen'est pas nécessaire car JSON.stringifyrenvoie déjà une chaîne.
mekwall

@MarcusEkwall: Afaik, ce serait toujours le cas encodeURIComponent, non?
Bergi

OK, ce n'est peut-être pas nécessaire, mais pensez-vous vraiment que cela ferait échouer la demande?
Bergi

Cela ne devrait pas le faire échouer, étant donné que c'est déjà une chaîne.
Kevin B

1
@Redsandro: Ouais, ça fait une "supposition intelligente". Cependant, la raison du paramètre n'est pas (seulement) que les gens veulent le rendre strict, mais plus qu'ils ne définissent pas les types MIME appropriés dans leurs réponses de serveur.
Bergi

5

Bien que je sache que de nombreuses architectures comme ASP.NET MVC ont des fonctionnalités intégrées pour gérer JSON.stringify en tant que contentType, ma situation est un peu différente, donc peut-être que cela pourrait aider quelqu'un à l'avenir. Je sais que cela m'aurait fait gagner des heures!

Étant donné que mes requêtes http sont gérées par une API CGI d'IBM (environnement AS400) sur un sous-domaine différent, ces requêtes sont d'origine croisée, d'où le jsonp. J'envoie en fait mon ajax via un ou plusieurs objets javascript. Voici un exemple de mon 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
Merci d'avoir ajouté plus de connaissances à cette question! La réponse satisfaisante avait déjà été donnée, mais j'ai voté pour la vôtre.
Redsandro le

1

Si vous renvoyez ceci à asp.net et que vous avez besoin des données dans request.form [], vous devrez définir le type de contenu sur "application / x-www-form-urlencoded; charset = utf-8"

Message original ici

Deuxièmement, débarrassez-vous du type de données, si vous n'attendez pas de retour, le POST attendra environ 4 minutes avant d'échouer. Voir ici

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.