Wie sende ich JSON anstelle einer Abfragezeichenfolge mit $ .ajax?


172

Kann jemand auf einfache Weise erklären, wie jQuery tatsächlich JSON anstelle einer Abfragezeichenfolge senden kann?

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

Dadurch wird Ihr sorgfältig vorbereiteter JSON in eine Abfragezeichenfolge konvertiert. Eines der ärgerlichen Dinge ist, dass alle array: []in Ihrem Objekt konvertiert werden array[]: [], wahrscheinlich aufgrund von Einschränkungen des Abfragestichs.


7
Das dataTypehat keinen Einfluss darauf, wie die Daten gesendet werden. Es gibt lediglich an, welchen Datentyp der Aufruf voraussichtlich zurückgeben wird. Wenn Sie dem Server datacontentTypecontentType: "application/json"
mitteilen

Danke fürs klarstellen. Aber warum muss ich in diesem Fall den Antworttyp clientseitig angeben, wenn der Server in der Antwort einen Inhaltstyp-Header bereitstellt?
Redsandro

2
Sie müssen nicht haben , um es angeben, wird standardmäßig jQuery versuchen und eine intelligente Vermutung auf den MIME - Typ der Antwort basiert. Wenn Sie es jedoch angeben, teilen Sie jQuery explizit mit, welchen Typ Sie vom Server erwarten, und jQuery versucht, die Antwort in ein Objekt dieses Typs zu konvertieren. Wenn Sie es nicht angeben und jQuery verlassen, kann dies dazu führen, dass jQuery die Antwort in ein unerwartetes Format konvertiert, obwohl Sie JSON vom Server gesendet haben. Weitere Informationen zum Datentyp finden
Nein,

Antworten:


256

Sie müssen verwenden, JSON.stringifyum Ihr Objekt zuerst in JSON zu serialisieren und dann das anzugeben, contentTypedamit Ihr Server versteht, dass es JSON ist. Dies sollte den Trick tun:

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

Beachten Sie, dass das JSONObjekt nativ in Browsern verfügbar ist, die JavaScript 1.7 / ECMAScript 5 oder höher unterstützen. Wenn Sie Legacy-Unterstützung benötigen, können Sie json2 verwenden .


14
Das wird nicht funktionieren, du vermisst contentType: 'application/json'.
Ohgodwhy

@ Ohgodwhy Oh ja. Das ging etwas zu schnell;)
Mekwall

1
Vielen Dank. Ich dachte, dataType hat sich darum gekümmert, aber ich habe das rückwärts verstanden. Irgendwelche Gedanken zur Angabe eines Zeichensatzes im Inhaltstyp, wie es Bergi in der anderen Antwort getan hat?
Redsandro

5
@ Redsandro Das sollte nicht nötig sein. Laut jQuery-Dokumenten:POST data will always be transmitted to the server using UTF-8 charset, per the W3C XMLHTTPRequest standard
Mekwall

1
@ Shorif2000 besser spät als nie ... das Problem ist, dass Sie in $_POSTPHP nur sehen können application/x-www-form-urlencoded, wenn Sie JSON-Daten lesen möchten, die Sie tun müssen, file_get_contents("php://input")und vielleicht dann ajson_decode()
santiago arizti

28

Nein, die dataTypeOption besteht darin, die empfangenen Daten zu analysieren.

Um JSON zu veröffentlichen, müssen Sie es selbst über kennzeichnen JSON.stringifyund die processDataOption auf setzen false.

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

Beachten Sie, dass nicht alle Browser das JSONObjekt unterstützen, und obwohl jQuery dies hat .parseJSON, ist kein Stringifier enthalten. Sie benötigen eine weitere Polyfill-Bibliothek.


4
Die Einstellung processDataauf falseist nicht erforderlich, da JSON.stringifybereits eine Zeichenfolge zurückgegeben wird.
Mekwall

@MarcusEkwall: Afaik, es wäre immer noch encodeURIComponented, nicht wahr ?
Bergi

OK, es wird möglicherweise nicht benötigt, aber glauben Sie wirklich, dass die Anfrage dadurch fehlschlagen würde?
Bergi

Es sollte nicht zum Scheitern führen, wenn man bedenkt, dass es sich bereits um eine Zeichenfolge handelt.
Kevin B

1
@ Redsandro: Ja, es macht eine "intelligente Vermutung". Der Grund für den Parameter ist jedoch nicht (nur), dass Benutzer ihn streng festlegen möchten, sondern vielmehr, dass sie in ihren Serverantworten keine geeigneten MIME-Typen festlegen.
Bergi

5

Obwohl ich weiß, dass viele Architekturen wie ASP.NET MVC über integrierte Funktionen verfügen, um JSON.stringify als Inhaltstyp zu behandeln, ist meine Situation etwas anders. Vielleicht kann dies in Zukunft jemandem helfen. Ich weiß, es hätte mir Stunden gespart!

Da meine http-Anforderungen von einer CGI-API von IBM (AS400-Umgebung) in einer anderen Subdomain verarbeitet werden, sind diese Anforderungen Ursprungsübergreifend, daher der jsonp. Ich sende meinen Ajax tatsächlich über Javascript-Objekte. Hier ist ein Beispiel für meinen 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
Vielen Dank, dass Sie dieser Frage mehr Wissen hinzugefügt haben! Die befriedigende Antwort war bereits gegeben worden, aber ich habe Ihre positiv bewertet.
Redsandro

1

Wenn Sie dies an asp.net zurücksenden und die Daten in request.form [] benötigen, müssen Sie den Inhaltstyp auf "application / x-www-form-urlencoded; charset = utf-8" setzen.

Originaler Beitrag hier

Zweitens: Entfernen Sie den Datentyp. Wenn Sie keine Rückgabe erwarten, wartet der POST etwa 4 Minuten, bevor er fehlschlägt. Siehe hier

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.