2012-10-02 153 views
150

容易的方式有人能解釋如何使jQueryquerystring代替發送實際jsonjQuery的AJAX,如何發送JSON,而不是查詢字符串

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

這將在事實上將您精心準備jsonquerystring。其中一個煩人的事情是,在你的對象的任何array: []將被轉換,因爲querysting的限制可能是array[]: []

-update-

正確的方法可以在下面的答案中找到:

$.ajax({ 
    url  : url, 
    dataType : 'json', 
    contentType: 'application/json; charset=UTF-8', // This is the money shot 
    data  : data, 
    type  : 'POST', 
    complete : callback // etc 
}); 

請注意,這需要合適的CORS頭的服務器端,並違背了一些例子在網絡上,允許報頭不能使用通配符。 (允許來源即可。)

{ 
    Content-Type     : 'application/json', 
    Access-Control-Allow-Origin : '*', 
    Access-Control-Allow-Headers : 'Content-Type' // You cannot use '*' 
} 

-update-

請注意jQuery現在將發送兩個請求,一個完成握手和一個符合實際的內容。這是稱爲pre-flight的正常HTTP行爲。第一個請求將是一個OPTIONS標題,以確定服務器是否實際上與計劃的請求兼容。

所以記住,如果你希望你的服務器是通用的,使用查詢字符串只發送一個請求。使用真JSON發送至少兩個請求,一個握手。

這與我的頭搞亂,所以我想我應該讓你(潛在的讀者)事先知道。

+6

'dataType'對數據的發送方式沒有任何影響。它只是規定了你希望通過調用返回**的數據類型。如果你想向服務器指明你在'data'屬性中指定了什麼類型的數據,你需要設置'contentType'屬性類似於'contentType:「application/json」' – Nope

+0

感謝您的澄清。但是在這種情況下,如果服務器在響應中提供了內容類型標題,爲什麼還需要指定響應類型客戶端? – Redsandro

+2

您不需要*指定它,默認情況下,jQuery將嘗試根據響應的MIME類型進行智能猜測。但是,通過指定它,您明確告訴jQuery您期望從服務器獲得哪種類型,並且jQuery將嘗試將響應轉換爲該類型的對象。沒有指定它,並且讓jQuery做出猜測可能會導致jQuery將響應轉換爲意外的格式,即使您從服務器發送了JSON。檢查文檔以獲取有關dataType的更多詳細信息:http://api.jquery.com/jQuery.ajax/ – Nope

回答

211

您需要使用JSON.stringify先系列化你的對象JSON,然後讓你的服務器理解它的JSON指定的內容類型。這應該做的伎倆:

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

注意,JSON對象是在瀏覽器中提供原生支持JavaScript 1.7/5的ECMAScript或更高版本。如果您需要傳統支持,您可以使用json2

+12

這不會工作,你缺少'contentType:'application/json 「'。 – Ohgodwhy

+0

@Ohgodwhy噢。這太快了;) – mekwall

+1

我們走了,現在它會工作。 +1 – Ohgodwhy

26

沒有,dataType option是用於分析接收到的數據。

要發佈JSON,您需要通過JSON.stringify自己將其串聯起來,並將processData選項設置爲false

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

請注意,並非所有瀏覽器都支持JSON對象,雖然jQuery有.parseJSON,它沒有stringifier包括在內;你需要另一個polyfill庫。

+2

因爲'JSON.stringify'已經返回一個字符串,所以'processData'設置爲'false'不是必須的。 – mekwall

+0

@MarcusEkwall:Afaik它仍然是'encodeURIComponent'ed,不是嗎? – Bergi

+0

好吧,它可能不是必需的,但是你真的認爲它會使請求失敗嗎? – Bergi

1

如果您將此信息發送回asp.net並需要request.form中的數據,那麼您需要將內容類型設置爲「application/x-www-form-urlencoded; charset = utf- 8"

原帖here

其次擺脫了數據類型的,如果你不能指望回報POST將等待約4分鐘失敗之前。看到here

5

雖然我知道像ASP.NET MVC的許多體系結構具有內置功能來處理JSON.stringify作爲contentType我的情況有點不同,所以也許這可能有助於未來的人。我知道這會節省我幾個小時!

由於我的http請求正由來自IBM(AS400環境)的CGI API在不同的子域中處理,所以這些請求是跨源的,因此是jsonp。我實際上通過javascript對象發送了我的ajax。這裏是我的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

感謝您爲此問題添加更多知識!滿意的答案已經給出,但我贊成你的。 – Redsandro

相關問題