2012-03-17 86 views
78

當我有這樣的代碼無法設置內容類型爲「應用/ JSON」在jQuery.ajax

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

在菲德勒我可以看到下面的原始請求

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 

但我什麼試圖將application/x-www-form-urlencoded設置爲application/json。但是這個代碼

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

生成奇怪的要求(我可以看到提琴手)

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 

這是爲什麼?什麼是OPTIONS當它應該在那裏?我的內容類型設置爲application/json的位置在哪裏?由於某種原因,請求參數已經消失。

更新1

在服務器端我有很簡單的RESTful服務。

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

但由於某種原因,我不能用參數調用此方法。

更新2

對不起,不回答這麼久。

我已經添加了這些頭到我的服務器響應

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

它並沒有幫助,我有不允許的方法從服務器錯誤。

這裏是我的小提琴手說

enter image description here

所以,現在我可以肯定,我的服務器接受POST,GET,OPTIONS(如果響應頭工作像我期望的那樣)。但爲什麼「方法不允許」?

在從服務器的WebView響應(你可以看到上面的圖片響應)看起來像這樣

enter image description here

+1

你應該嘗試JSON.stringfy()方法 – 2012-03-18 12:32:38

+0

NOP,沒有幫助這裏 – 2012-03-18 14:15:20

+0

看。這對我很好:http://stackoverflow.com/questions/9754767/cannot-set-content-type-to-application-json-in-jquery-ajax/18740041#18740041 – Fanda 2013-09-11 11:36:03

回答

24

我可以告訴你我是如何用它

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

與下一個答案相同。我不能不指定URL到服務器的所有服務功能託管 – 2012-03-18 14:23:07

+0

@VitaliiKorsakov我走了,你有沒有理清你的問題。 – 2012-03-18 15:09:52

+0

不,看到我的第一篇文章的其他信息 – 2012-03-18 16:09:05

65

會似乎從url選項中刪除http://可確保發送正確的HTTP POST標頭。

我不認爲你需要完全限定主機的名稱,只需使用相對URL如下。

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

的作品我的一個例子:

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

可能相關: jQuery $.ajax(), $.post sending "OPTIONS" as REQUEST_METHOD in Firefox

編輯: 一些更多的研究,我發現後的選項首部用於找出如果來自發起域的請求被允許。使用fiddler,我將以下內容添加到來自服務器的響應頭文件中。

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

一旦瀏覽器收到這個響應,它就會發送正確的POST請求和json數據。似乎默認的表單urlencoded內容類型被認爲是安全的,因此不會進行額外的跨域檢查。

看起來您需要將以前提到的標題添加到您的服務器響應OPTIONS請求。您當然應該將它們配置爲允許來自特定域的請求,而不是全部。

我用下面的jQuery來測試這個。

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

參考文獻:

+0

我想鬆散客戶端和服務器之間的耦合。服務器是RESTful服務,並且此服務的所有客戶端都應該知道它的URL。 – 2012-03-18 14:21:42

+0

你可以提供一些關於這個問題的場景的更多細節嗎?如果您的客戶將在不同的域中,您可能會遇到相同的原產地問題。 – Spike 2012-03-18 14:46:49

+0

我已經發布了關於服務器端的更多信息。現在服務器和客戶端都在本地主機上,但端口不同。後來他們很可能會在不同的領域。 – 2012-03-18 16:11:06

2

我發現這個問題here解決方案。不要忘記在IIS應用程序服務處理程序上允許動詞選項。

工作正常。謝謝AndréPedroso。 :-)

1

我有同樣的問題。我在jboss服務器上運行java rest應用程序。但我認爲這個解決方案與ASP .NET webapp類似。

Firefox會預先調用您的服務器/休息網址來檢查哪些選項是允許的。這是您的服務器沒有相應回覆的「選項」請求。如果這個OPTIONS調用被正確回覆,則執行第二個調用,這是對json內容的實際「POST」請求。

這隻發生在執行跨域呼叫時。在你的情況下調用'http://localhost:16329/Hello'而不是調用相同域下的url路徑'/ Hello'

如果打算進行跨域調用,則必須使用帶註釋的方法來增強休息服務類,選項「http請求。這是相應的Java實現:

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

所以我猜。NET你必須添加與

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

註釋的另一種方法,其中下面的標頭設置

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

我認出那些畫面,我用CodeFluentEntities,我已經有了解決方案,爲工作我也是。

我使用的建設:

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

,你可以看到,如果我用

contentType: "", 

contentType: "text/plain", //chrome 

,一切工作正常。

我不是100%確定這是所有你需要的,因爲我也改變了標題。

8

因此,所有你需要爲這個工作做的就是添加:

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

作爲一個字段到您的文章請求,它會工作。

+0

http://api.jquery.com/jquery.ajax/ 如果你看看它的文檔,它說,沒有指定它默認爲 'application/x-www-form-urlencoded; charset = UTF-8'(這就是爲什麼發生這種情況,Idk爲什麼只是設置contentType不起作用,你可能想檢查你有什麼版本的jQuery,如果你使用的是舊版本,就更新它)。 – 2016-01-20 16:08:47

+0

這不起作用。即使我輸入:「POST」,它會發送「OPTIONS」。 – user9645 2017-08-22 14:19:46

0

如果使用這樣的:

contentType: "application/json" 

AJAX將不會發送GET或POST PARAMS服務器....不知道爲什麼。

今天花了我幾個小時的時間來學習它。

只需使用:

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