JQuery.ajax'ta içerik türü 'application / json' olarak ayarlanamaz


106

Bu koda sahip olduğumda

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

Fiddler'da şu ham isteği görebiliyorum

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

Fakat benim çalışıyorum den ayarlanan içerik tipine olduğu uygulamanın / x-www-form-urlencoded için uygulama / json . Ama bu kod

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

Garip istek üretiyor (Fiddler'da görebildiğim)

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

Neden? Orada POST olması gerektiğinde OPTIONS nedir? Ve içerik türüm nerede application / json olarak ayarlandı? Ve bazı nedenlerden dolayı istek parametreleri gitti.

GÜNCELLEME 1

Sunucu tarafında gerçekten basit RESTful hizmetim var.

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

Ancak bazı nedenlerden dolayı bu yöntemi parametrelerle arayamıyorum.

GÜNCELLEME 2

Bu kadar uzun cevap vermediğim için üzgünüm.

Bu üstbilgileri sunucu yanıtıma ekledim

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

Yardımcı olmadı, Yönteme sunucudan izin verilmedi .

İşte kemancımın söylediği

görüntü açıklamasını buraya girin

Artık sunucumun POST, GET, OPTIONS kabul ettiğinden emin olabilirim (yanıt başlıkları beklediğim gibi çalışıyorsa). Ama neden "Yönteme izin verilmiyor"?

Sunucudan gelen WebView yanıtında ( yukarıdaki resimde Ham yanıtı görebilirsiniz ) şuna benzer

görüntü açıklamasını buraya girin


2
Eğer JSON.stringfy () yöntemini denemelisiniz
Amritpal Singh

Buraya bak. Bu benim için çok işe yarıyor: stackoverflow.com/questions/9754767/…
Fanda

Tam olarak aynı sorunu yaşıyorum, ancak arka uç olarak NodeJS ile çalışıyorum, ayrıca tüm OPTION isteklerini yalnızca kabul edilmekle kalmayıp aynı zamanda tüm OPTION isteklerinde 200 yanıtı zorunlu kılarak dilekçelerin geri kalanı beklendiği gibi çalışması için ayarladım
cevapsız

1
Merhaba @VitaliiKorsakov. Problemini çözdün mü? Aynı sorunu yaşıyorum, yani contentType'ı değiştiremiyorum.
worldterminator

1
Ben de aynı sorunu yaşadım ve yeni çalıştırdım .. çözüm şu sayfadaki cevapta: stackoverflow.com/questions/20295080/… .. özetlemek gerekirse: "contentType: 'application / json' kullanırken $ _POST'un doldurulduğuna güvenilemiyor. $ _POST yalnızca form kodlu içerik türleri için doldurulur. Bu nedenle, verilerinizi PHP ham girdisinden okumanız gerekir ".. Şimdi görüyorum ki sunucuda php kullanmıyorsunuz ama umarım bu bilgi bir şekilde yardımcı olur.
Sarah

Yanıtlar:


91

Görünüşe göre kaldırma http:// url seçeneğinden doğru HTTP POST başlığının gönderilmesini sağladığı .

Ana bilgisayarın adını tam olarak belirlemeniz gerektiğini düşünmüyorum, sadece aşağıdaki gibi göreceli bir URL kullanın.

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

İşe yarayan bir örnek:

        $.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;
        }
    });

Muhtemelen ilgili: jQuery $ .ajax (), $ .post Firefox'ta REQUEST_METHOD olarak "SEÇENEKLER" gönderiyor

Düzenleme: Biraz daha araştırmadan sonra OPTIONS başlığının, kaynak etki alanından gelen talebe izin verilip verilmediğini öğrenmek için kullanıldığını öğrendim. Fiddler'ı kullanarak sunucumdan yanıt başlıklarına aşağıdakileri ekledim.

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

Tarayıcı bu yanıtı aldıktan sonra json verileriyle doğru POST isteğini gönderdi. Görünüşe göre varsayılan biçim kodlu içerik türü güvenli kabul edilir ve bu nedenle fazladan etki alanları arası denetimlere tabi tutulmaz.

SEÇENEKLER isteğine yanıt olarak sunucularınıza önceden belirtilen başlıkları eklemeniz gerekecek gibi görünüyor. Elbette bunları tümü yerine belirli alanlardan gelen isteklere izin verecek şekilde yapılandırmalısınız.

Bunu test etmek için aşağıdaki jQuery'yi kullandım.

$.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);
  }
});​

Referanslar:


İstemci ve sunucu arasındaki bağlantıyı gevşetmek istiyorum. Sunucu RESTful hizmetidir ve bu hizmetin tüm istemcileri bunun URL'sini bilmelidir.
Vitalii Korsakov

Gönderinizde bu sorunun senaryosu hakkında biraz daha ayrıntı verebilir misiniz? Müşterileriniz farklı alanlarda olacaksa, aynı kaynak sorunlarıyla karşılaşabilirsiniz.
Mike Wade

Sunucu tarafı hakkında ek bilgi gönderdim. Şu anda sunucu ve istemci hem localhost'ta hem de bağlantı noktasında farklılık gösteriyor. Daha sonra büyük olasılıkla farklı alanlarda olacaklar.
Vitalii Korsakov

Karşılaştığınız sorun aynı menşe politikasıyla ilgili gibi görünüyor, jsonp'a ve bu bağlantılarla ilgili sorulara ek olarak cevabımda bağladığım soruya bakmaya değer olabilir . jquery etki alanları arası kılavuzu - Etki alanları arası isteklerle ilgili pek tecrübem yok ama umarım bu bağlantılar sizin için yararlı olacaktır.
Mike Wade

Bunun bir sorun olduğunu sanmıyorum çünkü herhangi bir parametreyi geçmediğimde her şey yolunda gidiyor ve content-type application / x-www-form-urlencoded. Ancak herhangi bir parametreyi geçemezsem POST isteğine ihtiyacım yok.
Vitalii Korsakov

42

Nasıl kullandığımı sana gösterebilirim

  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;
                }
            }
        });
    }

Bir sonraki cevapta olduğu gibi aynı şey. Tüm hizmet işlevlerinin barındırıldığı sunucuya url belirtemiyorum
Vitalii Korsakov

@VitaliiKorsakov ben gittim, problemini çözdün mü?
Amritpal Singh

Cevap için teşekkürler! Bunun başka bir yerde ifade edilmediğine inanamıyorum. Belirttiğiniz tür 'json' olduğunda JQuery json
gönderiyor

1
@JasonGoemaat jQuery'deki dataType parametresi yalnızca döndürülen yanıt gövdesini ayrıştırmak için kullanılır. Belgeleri okursanız, buna gerek olmadığını bile göreceksiniz. DataType için varsayılan değer akıllı tahmin değeridir. Sizin sorununuz jquery'deki veri özniteliğinin yapılandırılamamasıdır. Jquery'nin veri nesnesini nasıl ayrıştırması gerektiğini söyleyemezsiniz. Bu yüzden daha önce json'ı serileştirmeniz gerekiyor. Çünkü jquery yalnızca url-form-kodlamak için seri hale getirdiği için
Loïc Faure-Lacroix

12

Yani bunun çalışması için yapmanız gereken tek şey eklemek:

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

gönderi isteğiniz için bir alan olarak çalışacaktır.


api.jquery.com/jquery.ajax Dokümantasyona bakarsanız, bunu belirtmeden varsayılan olarak 'application / x-www-form-urlencoded; charset = UTF-8 '(bu yüzden oluyor. Neden sadece contentType'ı ayarlamanın işe yaramadığını açıklayın. Sahip olduğunuz jQuery sürümünü kontrol etmek ve eski bir sürümdeyseniz güncellemek isteyebilirsiniz).
Cody Jacques

Bu çalışmıyor. Sahip olsam bile type: "POST"gönderiyor OPTIONS.
user9645

5

Bu ekranları tanıdım, CodeFluentEntities kullanıyorum ve benim için de çalışan bir çözümüm var.

Bu yapıyı kullanıyorum:

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

gördüğün gibi, eğer kullanırsam

contentType: "",

veya

contentType: "text/plain", //chrome

Herşey yolunda gidiyor.

İhtiyacın olan tek şeyin bu olduğundan% 100 emin değilim, çünkü başlıkları da değiştirdim.


5

Bunu kullanırsanız:

contentType: "application/json"

AJAX sunucuya GET veya POST parametrelerini göndermiyor .... nedenini bilmiyorum.

Bugün öğrenmek saatlerimi aldı.

Sadece kullan:

$.ajax(
  { url : 'http://blabla.com/wsGetReport.php',
    data : myFormData, type : 'POST', dataType : 'json', 
    // contentType: "application/json", 
    success : function(wsQuery) { }
  }
)

1
ne yazık ki benim için doğru cevap. ContentType'ı atlayın ve sadece dataType'ı, birçok hizmetin düzgün bir şekilde gerçekleştirmediği CORS OPTIONS çöpünü atlamak için kullanın. Çok can sıkıcı.
Umopepisdn

2

Bu sorunun çözümünü buldum burada . IIS uygulama hizmeti işleyicisinde OPTIONS fiiline izin vermeyi unutmayın.

İyi çalışıyor. Teşekkürler André Pedroso. :-)


1

Ben de aynı sorunu yaşadım. Bir jboss sunucusunda bir java dinlenme uygulaması çalıştırıyorum. Ancak çözümün bir ASP .NET web uygulamasında benzer olduğunu düşünüyorum.

Firefox, hangi seçeneklere izin verildiğini kontrol etmek için sunucunuza / dinlenme URL'nize bir ön arama yapar. Bu, sunucunuzun uygun şekilde yanıtlamadığı "SEÇENEKLER" isteğidir. Bu OPTIONS çağrısı doğru yanıtlanırsa, json içeriğine sahip gerçek "POST" isteği olan ikinci bir çağrı gerçekleştirilir.

Bu yalnızca alanlar arası arama yapılırken olur. Senin durumunda arıyor 'http://localhost:16329/Hello , aynı alan adı altında bir url yolunu çağırmak yerine ' çağırmak '/ Merhaba'

Alanlar arası bir arama yapmayı düşünüyorsanız, dinlenme hizmeti sınıfınızı açıklamalı bir yöntemle geliştirmeniz gerekir, bu "SEÇENEKLER" http isteğini destekler. Bu, java uygulamasına göre:

@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();
    }
}

Sanırım .NET'te ek açıklamalı bir yöntem eklemeniz gerekiyor.

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

aşağıdaki başlıkların ayarlandığı yer

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

0

JSON verilerini POST isteği ile jquery ajax aracılığıyla gönderme çözümünü aldım. Aşağıdaki kodu kullandım

    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 );
      });


        });
    });

'Content-Type': 'text/plain'Ham json verilerini göndermek için başlıkta kullandım .
Çünkü Content-Type: 'application/json'OPTION'a dönüştürülen istek yöntemlerini kullanırsak, ancak Content-Type: 'test/plain'yöntemi kullanmak dönüştürülmez ve POST olarak kalır. Umarım bu birisine yardımcı olur.


3
Gerçekten OPTION biçimine dönüştürülmüyor, POST'a izin verilip verilmediğini kontrol etmek için bir CORS ön kontrol isteği gönderiyor. Bu doğru şekilde geri gelmediğinde POST gerçekleşmez.
Umopepisdn

0

Merhaba Bu iki satır benim için çalıştı.

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);
            }

Teşekkürler Prashant

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.