2012-10-02 7 views
150

Qualcuno può spiegare in modo semplice come effettuare jQuery inviare lo json effettivo anziché uno querystring?jQuery ajax, come inviare JSON invece di QueryString

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

Questa volontà, infatti, convertire il vostro preparato con cura json ad un querystring. Una delle cose più fastidiose è che qualsiasi array: [] nell'oggetto verrà convertito in array[]: [], probabilmente a causa delle limitazioni dello querysting.

-Ricalcola-

Il metodo corretto si possono trovare nelle risposte qui sotto:

$.ajax({ 
    url  : url, 
    dataType : 'json', 
    contentType: 'application/json; charset=UTF-8', // This is the money shot 
    data  : data, 
    type  : 'POST', 
    complete : callback // etc 
}); 

Si prega di notare che questo richiede una corretta CORS intestazioni lato server, e contrariamente ad alcuni esempi in rete, Allow-Headersnon può utilizzare caratteri jolly. (Allow-Origin can.)

{ 
    Content-Type     : 'application/json', 
    Access-Control-Allow-Origin : '*', 
    Access-Control-Allow-Headers : 'Content-Type' // You cannot use '*' 
} 

-Ricalcola-

Si prega di notare chejQuery sarà ora inviare due richieste, una per completare la stretta di mano e uno con il contenuto effettivo. Questo è normale comportamento di HTTP chiamato pre-volo. La prima richiesta sarà un'intestazione OPTIONS per determinare se il server è effettivamente compatibile con la richiesta pianificata.

Quindi, tenere a mente se si desidera che il server sia versatile, utilizzando un QueryString invia solo una richiesta. L'utilizzo di true JSON invia almeno due richieste, una per l'handshake.

Questo mi faceva impazzire, quindi ho pensato di farti sapere (il potenziale lettore) in anticipo.

+6

Il 'dataType' non incide su come i dati vengono inviati. Specifica semplicemente quale tipo di dati ci si aspetta che abbia ** restituito ** dalla chiamata. Se vuoi indicare al server quale tipo di dati stai specificando nella proprietà 'data' devi impostare la proprietà' contentType' simile a 'contentType:" application/json "' – Nope

+0

Grazie per aver chiarito. Ma in tal caso, perché devo specificare il tipo di risposta lato client se il server fornisce un'intestazione di tipo contenuto nella risposta? – Redsandro

+2

Non si dispone * di * per specificarlo, per impostazione predefinita jQuery proverà a fare un'ipotesi intelligente basata sul tipo MIME della risposta. Tuttavia, specificandolo si sta dicendo esplicitamente a jQuery che tipo si sta aspettando dal server e jQuery tenterà di convertire la risposta in un oggetto di quel tipo. Non specificarlo e lasciare che jQuery faccia una congettura potrebbe far sì che jQuery converta la risposta in un formato imprevisto, anche se hai inviato JSON dal server. Controlla la documentazione per maggiori dettagli sul dataType: http://api.jquery.com/jQuery.ajax/ – Nope

risposta

211

È necessario utilizzare JSON.stringify per serializzare prima l'oggetto su JSON, quindi specificare il tipo di contenuto in modo che il server comprenda che è JSON. Questo dovrebbe fare il trucco:

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

Nota che l'oggetto JSON è nativamente disponibili nei browser che supporta JavaScript 1.7/ECMAScript 5 o versione successiva. Se hai bisogno del supporto legacy puoi usare json2.

+12

Questo non funzionerà, ti manca 'contentType: 'application/json ''. – Ohgodwhy

+0

@Ohgodwhy Oh sì. È andato un po 'troppo veloce;) – mekwall

+1

Eccoci, ora funzionerà. +1 – Ohgodwhy

26

No, lo dataType option è per l'analisi dei dati ricevuti.

Per pubblicare JSON, è necessario effettuare la stringa da soli tramite JSON.stringify e impostare l'opzione processData su false.

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

Si noti che non tutti i browser supportano l'oggetto JSON, e anche se jQuery ha .parseJSON, non ha stringifier incluso; avrai bisogno di un'altra libreria di polyfill.

+2

L'impostazione 'processData' su' false' non è necessaria poiché 'JSON.stringify' restituisce già una stringa. – mekwall

+0

@MarcusEkwall: Afaik sarebbe ancora 'encodeURIComponent'ed, vero? – Bergi

+0

OK, potrebbe non essere necessario, ma pensi davvero che farebbe fallire la richiesta? – Bergi

1

Se si invia questo a asp.net e sono necessari i dati in request.form [], sarà necessario impostare il tipo di contenuto su "application/x-www-form-urlencoded; charset = utf- 8"

Original post here

in secondo luogo sbarazzarsi del tipo di dati, se il vostro non si aspettava un ritorno il POST attenderà per circa 4 minuti prima di guastarsi. Vedere here

5

Anche se so che molti architetture come ASP.NET MVC sono dotati di funzionalità per gestire JSON.stringify come il contentType la mia situazione è un po 'diversa quindi forse questo può aiutare qualcuno in futuro. So che mi avrebbe risparmiato ore!

Poiché le mie richieste http sono gestite da un'API CGI da IBM (ambiente AS400) su un sottodominio diverso, queste richieste sono di origine incrociata, da cui jsonp. In realtà invio la mia ajax tramite oggetto javascript. Ecco un esempio della mia 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

Grazie per aver aggiunto più conoscenza a questa domanda! La risposta soddisfacente era già stata data, ma ho svalutato la tua. – Redsandro