jQuery.ajax を利用してデータをサーバーに送信するには、以下のような形で data オプションに送信するデータを設定しますが、そのデータ(下のコードで言うと jsonString)の型は何にすべきかという話を書きます。
function apiHeroesPost() {
$.ajax({
type: "POST",
url: "api/heroes",
data: jsonString,
contentType: "application/json; charset=utf-8",
success: function (data) {
// ・・・省略・・・
},
error: function (jqXHR, textStatus, errorThrown) {
// ・・・省略・・・
}
});
}
答を先に書くと、
-
GET 要求(クエリ文字列としてデータを送信)の場合は JavaScript オブジェクト
-
POST 要求(コンテンツとしてデータを送信)の場合、(a) 受け取る側が application/x-www-form-urlencoded 形式を期待している場合は JavaScript オブジェクト、(b) ASP.NET Web API のように JSON 文字列を期待している場合は JSON 文字列
を data オプションに設定します。上のコードは POST 要求で「(b) ASP.NET Web API のように JSON 文字列を期待している」場合です。以下、POST 要求については (b) を前提に書きます。
jQuery の API Dcoumentation の説明によると、設定できる型は PlainObject or String or Array となっていますが、どれでもいいという訳ではありません。
その説明にある "It is converted to a query string, if not already a string. It's appended to the url for GET-requests." というところがポイントです。
具体的には、例えば、processData は設定しない(デフォルトの true)という条件で、
var j = { Id: 5, Name: "日本語" }; // j はオブジェクト
var jsonString = JSON.stringify(j); // jsonString は文字列
とした場合、GET 要求なら data:j とし、POST 要求なら data:jsonString とします。
data:j とすると j は application/x-www-form-urlencoded 形式に変換されて Id=5&Name=%E6%97%A5%E6%9C%AC%E8%AA%9E となり、GET 要求の際 URL にクエリ文字列として追加されます。(%E6%97%A5 ... %AA%9E は "日本語" の UTF-8 パーセントエンコーディング)
しかし、data:jsonString とすると、文字列は無変換なので、GET 要求の際そのままクエリ文字列として URL に追加されます。下の画像は Fiddler2 による GET 要求のキャプチャです。反転表示した部分を見てください。クエリ文字列が {"Id":5,"Name":"日本語"} となってるのが分かるでしょうか? (ブラウザに依存すると思いますが、IE9 では "日本語" は Shift_JIS になり、下の画像では 22 93 FA 96 7B 8C EA 22 というバイト列になっています)
POST 要求の場合も、data の変換の仕方は同じ(オブジェクトはクエリ文字列形式に変換、文字列は無変換)になります。しかし、POST 要求はコンテンツとしてデータを送信しますので、GET 要求と違って data:j(j はオブジェクト)ではダメです。
data:jsonString として文字列を設定すればそのまま UTF-8 コードのコンテンツとして送信されますので、jsonString が有効な JSON 文字列なら期待通りの結果が得られるはずです。(注:contentType: "application/json; charset=utf-8" が前提です)
たぶん普通は、GET と POST の使い分けは以下のようにする(参考:jQuery - AJAX get() and post() Methods)と思います。
-
GET - Requests data from a specified resource
-
POST - Submits data to be processed to a specified resource
なので、データを送信する際は POST 要求、jQuery.ajax の data には JSON 文字列を設定ということしか頭になかったです。それでちょっとハマってしまったので、備忘録として残しておくことにしました。