Bagaimana cara mengirim JSON alih-alih string kueri dengan $ .ajax?

172

Dapatkah seseorang menjelaskan dengan cara mudah bagaimana membuat jQuery mengirim JSON yang sebenarnya, bukan string kueri?

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

Ini sebenarnya akan mengkonversi JSON Anda disiapkan dengan hati-hati ke string kueri. Salah satu hal yang mengganggu adalah benda apa pun yang ada array: []di objek Anda akan dikonversi array[]: [], mungkin karena batasan dari sengatan kueri.

Redsandro
sumber
7
Tidak dataTypeada hubungannya dengan bagaimana data dikirim. Ini hanya menentukan jenis data yang Anda harapkan telah dikembalikan oleh panggilan. Jika Anda ingin menunjukkan ke server jenis data apa yang Anda tentukan di dataproperti, Anda perlu mengatur contentTypeproperti yang mirip dengancontentType: "application/json"
Tidak
Terima kasih telah mengklarifikasi. Tetapi dalam kasus itu, mengapa saya perlu menentukan tipe respons sisi klien jika server menyediakan header tipe konten dalam respons?
Redsandro
2
Anda tidak harus menentukannya, secara default jQuery akan mencoba dan membuat tebakan cerdas berdasarkan jenis respons MIME. Namun, dengan menentukan itu, Anda memberi tahu jQuery secara eksplisit jenis apa yang Anda harapkan dari server dan jQuery akan berusaha mengubah respons menjadi objek jenis itu. Tidak menentukannya dan meninggalkan jQuery menebak dapat mengakibatkan jQuery mengubah respons menjadi format yang tidak terduga, meskipun Anda mengirim JSON dari server. Periksa dokumentasi untuk detail lebih lanjut tentang tipe data: api.jquery.com/jQuery.ajax
Tidak
Kemungkinan duplikat Jquery Ajax Posting json ke webservice
Madura Pradeep

Jawaban:

256

Anda perlu menggunakan JSON.stringifyuntuk membuat serialkan objek Anda terlebih dahulu ke JSON, dan kemudian tentukan contentTypeagar server Anda memahami JSON itu. Ini harus melakukan trik:

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

Perhatikan bahwa JSONobjek tersebut tersedia secara native di browser yang mendukung JavaScript 1.7 / ECMAScript 5 atau lebih baru. Jika Anda membutuhkan dukungan sebelumnya, Anda dapat menggunakan json2 .

mekwall
sumber
14
Ini tidak akan berhasil, Anda hilang contentType: 'application/json'.
Ohgod
@ Oh, mengapa Oh ya. Itu berjalan agak terlalu cepat;)
mekwall
1
Terima kasih. Saya pikir dataType menangani ini, tetapi saya mendapatkannya mundur. Adakah pemikiran tentang menentukan rangkaian karakter dalam tipe konten seperti yang dilakukan Bergi di jawaban yang lain?
Redsandro
5
@Redsandro Itu tidak perlu. Menurut jQuery docs:POST data will always be transmitted to the server using UTF-8 charset, per the W3C XMLHTTPRequest standard
mekwall
1
@ shorif2000 lebih baik terlambat daripada tidak pernah ... masalahnya adalah bahwa di $_POSTdalam php Anda hanya dapat melihat application/x-www-form-urlencoded, jika Anda ingin membaca data json yang harus Anda lakukan file_get_contents("php://input")dan mungkin kemudianjson_decode()
santiago arizti
28

Tidak, dataTypeopsinya adalah untuk mem-parsing data yang diterima.

Untuk mengeposkan JSON, Anda harus menyesuaikannya sendiri JSON.stringifydan mengatur processDataopsi false.

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

Perhatikan bahwa tidak semua browser mendukung JSONobjek tersebut, dan meskipun jQuery memilikinya .parseJSON, ia tidak menyertakan stringifier; Anda akan membutuhkan perpustakaan polyfill lain.

Bergi
sumber
4
Pengaturan processDatake falsetidak perlu karena JSON.stringifysudah mengembalikan string.
mekwall
@ MarscusEkwall: Afaik masih akan diedit encodeURIComponent, bukan?
Bergi
OKE, mungkin tidak diperlukan, tetapi apakah Anda benar-benar berpikir itu akan membuat permintaan gagal?
Bergi
Seharusnya tidak membuatnya gagal, mengingat itu sudah string.
Kevin B
1
@Redsandro: Ya, itu melakukan "tebakan cerdas". Namun, alasan parameternya bukan (hanya) bahwa orang ingin membuatnya ketat, tetapi lebih karena mereka tidak menetapkan tipe MIME yang sesuai dalam respons server mereka.
Bergi
5

Meskipun saya tahu banyak arsitektur seperti ASP.NET MVC memiliki fungsionalitas bawaan untuk menangani JSON.stringify sebagai contentType situasi saya sedikit berbeda jadi mungkin ini dapat membantu seseorang di masa depan. Saya tahu itu akan menyelamatkan saya berjam-jam!

Karena permintaan http saya sedang ditangani oleh API CGI dari IBM (lingkungan AS400) pada subdomain yang berbeda, permintaan ini berasal dari silang, karenanya jsonp. Saya sebenarnya mengirim ajax saya melalui objek javascript. Berikut adalah contoh dari POST ajax saya:

 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
       });
yardpenalty.com
sumber
2
Terima kasih telah menambahkan lebih banyak pengetahuan untuk pertanyaan ini! Jawaban yang memuaskan sudah diberikan, tetapi saya membenarkan jawaban Anda.
Redsandro
1

Jika Anda mengirim ini kembali ke asp.net dan memerlukan data di request.form [] maka Anda perlu mengatur tipe konten menjadi "application / x-www-form-urlencoded; charset = utf-8"

Posting asli di sini

Kedua singkirkan Datatype, jika Anda tidak mengharapkan pengembalian, POST akan menunggu sekitar 4 menit sebelum gagal. Lihat di sini

Rubah
sumber