Tidak dapat menyetel tipe konten ke 'application / json' di jQuery.ajax

106

Ketika saya memiliki kode ini

$.ajax({
    type: 'POST',
    //contentType: "application/json",
    url: 'http://localhost:16329/Hello',
    data: { name: 'norm' },
    dataType: 'json'
});

di Fiddler saya bisa melihat permintaan mentah berikut

POST http://localhost:16329/Hello HTTP/1.1
Host: localhost:16329
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:14693/WebSite1/index.html
Content-Length: 9
Origin: http://localhost:14693
Pragma: no-cache
Cache-Control: no-cache

name=norm

Tapi yang saya coba adalah mengatur tipe konten dari application / x-www-form-urlencoded ke application / json . Tapi kode ini

$.ajax({
    type: "POST",
    contentType: "application/json",
    url: 'http://localhost:16329/Hello',
    data: { name: 'norm' },
    dataType: "json"
});

Menghasilkan permintaan aneh (yang dapat saya lihat di Fiddler)

OPTIONS http://localhost:16329/Hello HTTP/1.1
Host: localhost:16329
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Origin: http://localhost:14693
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Pragma: no-cache
Cache-Control: no-cache

Mengapa demikian? Apa OPTIONS ketika harus POST di sana? Dan di mana tipe konten saya disetel ke application / json? Dan parameter permintaan telah hilang karena beberapa alasan.

UPDATE 1

Di sisi server saya memiliki layanan RESTful yang sangat sederhana.

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class RestfulService : IRestfulService
{
    [WebInvoke(
        Method = "POST",
        UriTemplate = "Hello",
        ResponseFormat = WebMessageFormat.Json)]
    public string HelloWorld(string name)
    {
        return "hello, " + name;
    }
}

Tetapi untuk beberapa alasan saya tidak dapat memanggil metode ini dengan parameter.

UPDATE 2

Maaf karena tidak menjawab terlalu lama.

Saya telah menambahkan tajuk ini ke respons server saya

 Access-Control-Allow-Origin: *
 Access-Control-Allow-Headers: Content-Type
 Access-Control-Allow-Methods: POST, GET, OPTIONS

Itu tidak membantu, saya memiliki Metode tidak diizinkan kesalahan dari server.

Inilah yang dikatakan pemain biola saya

masukkan deskripsi gambar di sini

Jadi, sekarang saya bisa yakin bahwa server saya menerima POST, GET, OPTIONS (jika header respons berfungsi seperti yang saya harapkan). Tetapi mengapa "Metode tidak diperbolehkan"?

Dalam WebView respon dari server (Anda bisa melihat respon mentah pada gambar di atas) terlihat seperti ini

masukkan deskripsi gambar di sini

Vitalii Korsakov
sumber
2
Anda harus mencoba metode JSON.stringfy ()
Amritpal Singh
Lihat di sini. Ini bekerja dengan sangat baik untuk saya: stackoverflow.com/questions/9754767/…
Fanda
Saya mengalami masalah yang sama persis, tetapi saya bekerja dengan NodeJS sebagai backend, saya juga mengatur semua permintaan OPTION tidak hanya untuk diterima tetapi juga untuk memaksa 200 tanggapan pada semua permintaan OPTION sehingga petisi lainnya berfungsi seperti yang diharapkan tanpa tanggapan ...
HeberLZ
1
Hai @Vitali. Sudahkah Anda memecahkan masalah Anda? Saya menemui masalah yang sama, yaitu tidak dapat mengubah contentType.
worldterminator
1
Saya memiliki masalah yang sama dan baru saja berhasil .. solusinya ada pada jawaban di halaman ini: stackoverflow.com/questions/20295080/… .. untuk menyimpulkannya: "Saat menggunakan contentType: 'application / json' Anda akan tidak dapat mengandalkan $ _POST yang diisi. $ _POST hanya diisi untuk jenis konten yang dikodekan formulir. Dengan demikian, Anda perlu membaca data Anda dari input mentah PHP ".. Saya lihat sekarang Anda tidak menggunakan php di server sisi tetapi semoga informasi ini membantu dalam beberapa cara.
Sarah

Jawaban:

91

Tampaknya menghapus http:// dari opsi url memastikan header HTTP POST yang benar dikirim.

Saya rasa Anda tidak perlu sepenuhnya memenuhi syarat nama host, cukup gunakan URL relatif seperti di bawah ini.

   $.ajax({
      type: "POST",
      contentType: "application/json",
      url: '/Hello',
      data: { name: 'norm' },
      dataType: "json"
   });

Contoh saya yang berhasil:

        $.ajax({
            type: "POST",
            url: siteRoot + "api/SpaceGame/AddPlayer",
            async: false,
            data: JSON.stringify({ Name: playersShip.name, Credits: playersShip.credits }),
            contentType: "application/json",
            complete: function (data) {
            console.log(data);
            wait = false;
        }
    });

Mungkin terkait: jQuery $ .ajax (), $ .post mengirim "OPTIONS" sebagai REQUEST_METHOD di Firefox

Edit: Setelah beberapa penelitian lebih lanjut saya menemukan header OPTIONS digunakan untuk mengetahui apakah permintaan dari domain asal diperbolehkan. Menggunakan fiddler, saya menambahkan yang berikut ini ke header respons dari server saya.

 Access-Control-Allow-Origin: *
 Access-Control-Allow-Headers: Content-Type
 Access-Control-Allow-Methods: POST, GET, OPTIONS

Setelah browser menerima respons ini, maka permintaan POST yang benar dengan data json dikirim. Tampaknya jenis konten berkode-url bentuk default dianggap aman sehingga tidak menjalani pemeriksaan lintas domain ekstra.

Sepertinya Anda perlu menambahkan tajuk yang disebutkan sebelumnya ke server Anda untuk menanggapi permintaan OPTIONS. Anda tentu saja harus mengonfigurasinya untuk mengizinkan permintaan dari domain tertentu, bukan semua.

Saya menggunakan jQuery berikut untuk menguji ini.

$.ajax({
   type: "POST",
   url: "http://myDomain.com/path/AddPlayer",
   data: JSON.stringify({
      Name: "Test",
       Credits: 0
   }),
   //contentType: "application/json",
   dataType: 'json',
   complete: function(data) {
       $("content").html(data);
  }
});​

Referensi:

Mike Wade
sumber
Saya ingin melepaskan kopling antara klien dan server. Server adalah layanan RESTful dan semua klien layanan ini harus mengetahui url ke sana.
Vitalii Korsakov
Bisakah Anda memberikan beberapa detail lebih lanjut di posting Anda tentang skenario pertanyaan ini? Jika klien Anda akan berada di domain yang berbeda, Anda mungkin mengalami masalah asal yang sama.
Mike Wade
Saya telah memposting info tambahan tentang sisi server. Saat ini server dan klien keduanya di localhost tetapi berbeda dalam port. Nanti kemungkinan besar mereka akan berada di domain yang berbeda.
Vitalii Korsakov
Sepertinya masalah yang Anda alami berkaitan dengan kebijakan asal yang sama, mungkin ada baiknya melihat jsonp dan pertanyaan yang saya tautkan dalam jawaban saya selain pertanyaan terkait tautan ini . panduan lintas domain jquery - Saya tidak memiliki banyak pengalaman dengan permintaan lintas domain, tetapi semoga tautan tersebut berguna bagi Anda.
Mike Wade
Saya tidak berpikir bahwa ini adalah masalah karena semuanya berfungsi dengan baik ketika saya tidak memberikan parameter apa pun dan jenis konten adalah application / x-www-form-urlencoded. Tetapi saya tidak memerlukan permintaan POST jika saya tidak dapat meneruskan parameter apa pun.
Vitalii Korsakov
41

Saya dapat menunjukkan kepada Anda bagaimana saya menggunakannya

  function GetDenierValue() {
        var denierid = $("#productDenierid").val() == '' ? 0 : $("#productDenierid").val();
        var param = { 'productDenierid': denierid };
        $.ajax({
            url: "/Admin/ProductComposition/GetDenierValue",
            dataType: "json",
            contentType: "application/json;charset=utf-8",
            type: "POST",
            data: JSON.stringify(param),
            success: function (msg) {
                if (msg != null) {
                    return msg.URL;
                }
            }
        });
    }
Amritpal Singh
sumber
Hal yang sama seperti pada jawaban berikutnya. Saya tidak bisa tidak menentukan url ke server tempat semua fungsi layanan di-host
Vitalii Korsakov
@VitaliiKorsakov saya pergi, sudahkah Anda menyelesaikan masalah Anda.
Amritpal Singh
Terima kasih atas jawabannya! Saya tidak percaya ini tidak disebutkan di tempat lain. Sepertinya JQuery akan memposting json ketika jenis yang Anda tentukan adalah 'json', tapi saya rasa tidak ...
Jason Goemaat
1
@JasonGoemaat parameter dataType di jQuery hanya digunakan untuk mengurai isi respons yang dikembalikan. Jika Anda membaca dokumentasinya, Anda akan melihat bahwa itu bahkan tidak diperlukan. Nilai default untuk dataType adalah tebakan cerdas. Masalah Anda adalah atribut data di jquery tidak dapat dikonfigurasi. Anda tidak dapat mengetahui bagaimana jquery harus mengurai objek data. Itu sebabnya Anda harus membuat serial json sebelumnya. Karena jquery hanya membuat serial ke url-form-encode
Loïc Faure-Lacroix
12

Jadi yang perlu Anda lakukan agar ini berfungsi adalah menambahkan:

headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
}

sebagai bidang untuk permintaan posting Anda dan itu akan berhasil.

Cody Jacques
sumber
api.jquery.com/jquery.ajax Jika Anda melihat di dokumentasinya, dikatakan bahwa tanpa menentukan defaultnya adalah 'application / x-www-form-urlencoded; charset = UTF-8 '(itulah sebabnya hal itu terjadi. Idk mengapa hanya menyetel contentType tidak berfungsi. Anda mungkin ingin memeriksa versi jQuery yang Anda miliki dan memperbarui jika Anda menggunakan versi lama).
Cody Jacques
Ini tidak bekerja. Meskipun saya punya type: "POST", itu mengirim OPTIONS.
pengguna9645
5

Saya mengenali layar tersebut, saya menggunakan CodeFluentEntities, dan saya juga mendapatkan solusi yang berhasil untuk saya.

Saya menggunakan konstruksi itu:

$.ajax({
   url: path,
   type: "POST",
   contentType: "text/plain",
   data: {"some":"some"}
}

seperti yang Anda lihat, jika saya menggunakan

contentType: "",

atau

contentType: "text/plain", //chrome

Semuanya bekerja dengan baik.

Saya tidak 100% yakin hanya itu yang Anda butuhkan, karena saya juga telah mengubah header.

Alexey Avdeyev
sumber
5

Jika Anda menggunakan ini:

contentType: "application/json"

AJAX tidak akan mengirim parameter GET atau POST ke server .... tidak tahu mengapa.

Aku butuh waktu berjam-jam untuk memahaminya hari ini.

Gunakan saja:

$.ajax(
  { url : 'http://blabla.com/wsGetReport.php',
    data : myFormData, type : 'POST', dataType : 'json', 
    // contentType: "application/json", 
    success : function(wsQuery) { }
  }
)
Luis Arturo Erique Guajala
sumber
1
sayangnya jawaban yang benar untuk saya. Hilangkan contentType dan cukup gunakan dataType untuk melewati sampah CORS OPTIONS yang tidak diterapkan dengan benar oleh banyak layanan. Sangat mengganggu.
Umopepisdn
2

Saya menemukan solusi untuk masalah ini di sini . Jangan lupa untuk mengizinkan PILIHAN verba pada penangan layanan aplikasi IIS.

Bekerja dengan baik. Terima kasih André Pedroso. :-)

Fanda
sumber
1

Saya memiliki masalah yang sama. Saya menjalankan aplikasi java rest di server jboss. Tapi saya pikir solusinya serupa pada aplikasi web ASP .NET.

Firefox melakukan panggilan awal ke server / url istirahat Anda untuk memeriksa opsi mana yang diizinkan. Itu adalah permintaan "OPTIONS" yang tidak dibalas oleh server Anda. Jika panggilan OPTIONS ini dijawab dengan benar, panggilan kedua dilakukan yang merupakan permintaan "POST" sebenarnya dengan konten json.

Ini hanya terjadi saat melakukan panggilan lintas domain. Dalam kasus Anda menelepon 'http://localhost:16329/Hello ' alih-alih memanggil jalur url di bawah domain yang sama '/ Hello'

Jika Anda bermaksud untuk membuat panggilan lintas domain, Anda harus meningkatkan kelas layanan istirahat Anda dengan metode beranotasi yang mendukung permintaan http "OPTIONS". Ini adalah implementasi java yang sesuai:

@Path("/rest")
public class RestfulService {

    @POST
    @Path("/Hello")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.TEXT_PLAIN)
    public string HelloWorld(string name)
    {
        return "hello, " + name;
    }

//THIS NEEDS TO BE ADDED ADDITIONALLY IF MAKING CROSS-DOMAIN CALLS

    @OPTIONS
    @Path("/Hello")
    @Produces(MediaType.TEXT_PLAIN+ ";charset=utf-8")
    public Response checkOptions(){
        return Response.status(200)
        .header("Access-Control-Allow-Origin", "*")
        .header("Access-Control-Allow-Headers", "Content-Type")
        .header("Access-Control-Allow-Methods", "POST, OPTIONS") //CAN BE ENHANCED WITH OTHER HTTP CALL METHODS 
        .build();
    }
}

Jadi saya kira di .NET Anda harus menambahkan metode tambahan yang dianotasi

[WebInvoke(
        Method = "OPTIONS",
        UriTemplate = "Hello",
        ResponseFormat = WebMessageFormat.)]

tempat tajuk berikut ditetapkan

.header("Access-Control-Allow-Origin", "*")
        .header("Access-Control-Allow-Headers", "Content-Type")
        .header("Access-Control-Allow-Methods", "POST, OPTIONS")
Vincent
sumber
0

Saya mendapat solusi untuk mengirim data JSON dengan permintaan POST melalui jquery ajax. Saya menggunakan kode di bawah ini

    var data = new Object();
    data.p_clientId = 4;
    data =  JSON.stringify(data);

    $.ajax({
      method: "POST",
      url: "http://192.168.1.141:8090/api/Client_Add",
      data: data,
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'text/plain'
    }
    })
      .done(function( msg ) {
        alert( "Data Saved: " + msg );
      });


        });
    });

Saya menggunakan 'Content-Type': 'text/plain'header untuk mengirim data json mentah.
Karena jika kita menggunakan Content-Type: 'application/json'metode request yang dikonversi ke OPTION, tetapi menggunakan Content-Type: 'test/plain'metode tersebut tidak dapat dikonversi dan tetap sebagai POST. Semoga ini bisa membantu seseorang.

Rahul Aparajit
sumber
3
Ini tidak benar-benar mengubah ke OPTION, itu mengirim permintaan preflight CORS untuk memeriksa untuk melihat apakah POST diizinkan. Jika ini tidak kembali dengan benar, POST tidak akan terjadi.
Umopepisdn
0

Hai, dua baris ini berhasil untuk saya.

contentType: "application / json; charset = utf-8", dataType: "json"

 $.ajax({
            type: "POST",
            url: "/v1/candidates",
            data: obj,
            **contentType:"application/json; charset=utf-8",
            dataType:"json",**
            success: function (data) {
                table.row.add([
                    data.name, data.title
                ]).draw(false);
            }

Terima kasih, Prashant

Kumar Prashant
sumber