読者です 読者をやめる 読者になる 読者になる

miso_soup3 Blog

主に ASP.NET 関連について書いています。

WEB フォーム送信の仕組みを理解する

ASP.NET MVC 深夜連絡 ASP.NET MVC Advent Calendar 2013

この記事は、ASP.NET MVC 入門者向けに書いています。

f:id:miso_soup3:20131203030836p:plain

ASP.NET MVC において、フォームの入力値がどのように HTTP 通信で送信されるか把握することは重要です。この記事では次のことについて確認します。

  • フォーム送信時の HTTP リクエスト
  • GET と POST の使い分け

問題に解答する形で解説しようと思います。

問題

問題1

次のような入力フォームを用意し、送信ボタンを押した場合、サーバーへ送信する HTTP リクエストの次の項目はどのようになるでしょうか。

  • HTTP メソッド
  • URL
  • ヘッダー Content-Type
  • Body

入力フォーム:
f:id:miso_soup3:20131203015314p:plain
入力フォーム HTML:

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
	<title></title>
</head>
<body>

	<form method="post" action="http://localhost/">

		<input type="hidden" id="phone-hidden" name="phone" value="123456" />
		<div>
			city:<input type="text" id="city-hidden" name="city" value="" />
		</div>
		<div>
			accept:<input type="checkbox" id="accept-check" name="accept" />
		</div>
		<div>
			<select id="gender-select" name="gender">
				<option value="female">女性</option>
				<option value="male">男性</option>
			</select>
		</div>

		<input type="submit" value="送信" />

	</form>

</body>
</html>
問題2

問題1の入力フォームの HTML にて、form タグの method="post" を method="get" に変更します。送信ボタンを押した場合、先ほどの HTTP リクエストの項目はどのようになるでしょうか。

確認手順

問題1を解く

この問題は、Web のフォーム送信の仕組みを確認するものであるため、Visual Studio は使用しません。問題1の解答を確認するための手順を書きます。(1つの例です)

送信される HTTP リクエストの中身を確認するために、Fiddler をインストールしておきます。

入力フォームの HTML をコピペし、メモ帳等のエディターに貼り付けて「input.htm」で保存します。 (htm 形式であればファイル名はなんでもOK)
f:id:miso_soup3:20131203020459p:plain

Fiddler を起動しておきます。
f:id:miso_soup3:20131203020338p:plain

input.htm をブラウザで開き、適当に入力フォームに値を入れ、送信ボタンを押します。
f:id:miso_soup3:20131203020645p:plain
(この時、http://localhost/ 宛に適当に送信しているので、ブラウザではエラー画面が表示されると思いますが、今は関係ないのでスルーします。)

Fiddler を開き、左から localhost 宛ての HTTP 通信を選択します。
右側では、「Inspectors」タブの「Raw」を開きます。これで、送信した HTTP リクエストの生の中身を確認できます。

青で囲んだ箇所が、確認する項目が記されている部分です。

f:id:miso_soup3:20131203024523p:plain

確認項目
HTTP メソッド POST
URL http://localhost/
ヘッダー Content-Type application/x-www-form-urlencoded
Body phone=123456&city=%1B%24BEl5%7E%1B%28B&accept=on&gender=female

Body に、input タグの name と入力した値がペアで格納されていることがわかります。値は URL エンコードされています。

URL エンコードされた値を確認するためには URL デコードする必要があります。
Fiddler を開いた状態で、「Ctrl」キー+「E」キーを押します。

f:id:miso_soup3:20131203022534p:plain

上半分の欄に、Body の値をコピペします。URL デコードされた結果が下半分に表示されますが、日本語を入力した場合は文字化けされます。文字化けを解除するには、「Enboding」を押して文字コードを選択するバーを表示させ、Inputに「日本語....」を選択します。これで、URL エンコードされた Body の値を確認することができます。

問題2を解く

「input.htm」をエディタで開き、form タグの method="post" を method="get" に変更し、保存します。

先ほどの問題1の時と同様に、入力フォームに値を入れ、送信ボタンを押し、Fiddler で HTTP リクエストの中身を確認します。

f:id:miso_soup3:20131203023553p:plain

確認項目
HTTP メソッド GET
URL http://localhost/?phone=123456&city=%1B%24BEl5~%1B%28B&accept=on&gender=female
ヘッダー Content-Type (無し)
Body (無し)

問題1とは違い、HTTP メソッドが POST ではなく GET へ、URL の後ろに Body に格納されていた入力値が格納されていることがわかります。

大事なこと

  • 1. 入力フォーム(Form タグ)を使ってサーバーに値を送信する際、GET で送信する方法と POST で送信する方法の2つがあります。
  • 2. どちらで送信するかは、Form タグの method 属性の値で決定されます。値を指定しない場合はデフォルトの GET で送信されます。
  • 3. GET と POST では、送信時の HTTP リクエストの内容が大きく変わります。
    • 入力値が格納される場所は、GET の場合はクエリ文字列、POST の場合は Body になります。
  • 4. 入力値は、キー(input タグの name 属性の値)と値(input タグの value 属性の値)のペアで送信されます。

ASP.NET MVC では、この送信されたキーと値のぺアを元にモデルバインドが働きます。

GET と POST を使い分ける

このフォームでの送信は、GET と POST の2つの方法しか利用できません。
(HTTP メソッドには、GET と POST の他に PUT や DELETE 等があります。)

GET と POST のどちらを使用するかは、用途によって使い分けます。

サーバー側のデータを変更するような送信の場合は POST を
サーバー側のデータを変更せずに取得する場合は GET を選択します。

POST の例はブログの投稿やプロフィールの更新、GET の例は Google 等の検索があります。
http://www.kanzaki.com/docs/html/htminfo32.html#get-post に詳しい説明があるので是非ご覧下さい。

Next Step : HTML 5 では

HTML4.01からHTML5へのバージョンアップによる変更点
form要素は、HTML5ではaccept属性が廃止され、autocomplete属性・novalidate属性が追加されています。

http://www.htmq.com/html5/form.shtml
チートシート

今回の内容を図でまとめてみました。

f:id:miso_soup3:20131203030821p:plain

by 深夜連絡 ASP.NET MVC な Web アプリ Advent Calendar 2013 2 日目