application/x-www-form-urlencoded エンコード
HTMLフォームデータがapplication/x-www-form-urlencodedでエンコードされる仕組みを解説。標準URLエンコードとの違い、スペースの+表現を学びましょう。
Character
form data
Encoded
+
詳細な説明
application/x-www-form-urlencodedコンテンツタイプは、HTMLフォーム送信のデフォルトエンコードです。URL percent-encodingと密接に関連していますが、最も顕著な違いとして、スペースが%20ではなく+にエンコードされます。
フォームエンコードの仕組み:
- 各フォームフィールドの名前と値をエンコードする
- スペースを
+に置換する - 英数字以外の文字(
-、_、.、*を除く)をpercent-encodingする - 名前と値のペアを
=で結合する - ペアを
&で区切る
例:
フォームフィールド:
name: "John Doe"
message: "Hello & goodbye!"
エンコードされたボディ:
name=John+Doe&message=Hello+%26+goodbye%21
JavaScriptでの動作:
// URLSearchParams はフォームエンコードされた出力を生成する
const formData = new URLSearchParams({
name: "John Doe",
message: "Hello & goodbye!"
});
formData.toString();
// "name=John+Doe&message=Hello+%26+goodbye%21"
// フォームエンコードで fetch する
fetch("/api/submit", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: formData.toString()
});
// 標準URLエンコードとの比較
encodeURIComponent("John Doe"); // "John%20Doe" (フォームエンコードではない)
RFC 3986 percent-encodingとの主な違い:
| 特徴 | フォームエンコード | RFC 3986 |
|---|---|---|
| スペース | + |
%20 |
アスタリスク * |
エンコードしない | エンコードしない |
チルダ ~ |
%7Eとしてエンコード(レガシー) |
エンコードしない |
フォームエンコードが使用される場面:
- HTML
<form method="GET">送信(データはURLクエリ文字列に入る) - デフォルトenctypeでのHTML
<form method="POST">送信 Content-Type: application/x-www-form-urlencodedを使用するAJAXリクエスト- OAuth 1.0署名ベース文字列
フォームエンコードを使用すべきでない場面:
- ファイルアップロード(代わりに
multipart/form-dataを使用) - JSON APIリクエスト(
application/jsonを使用) - URLパスセグメント(標準percent-encodingを使用)
落とし穴: サーバーがクエリパラメータを受信する際、+をスペースとしてデコードするかリテラルのプラス記号としてデコードするかを判断する必要があります。HTMLフォームGET送信からのクエリ文字列はフォームエンコード(+ = スペース)を使用しますが、手動で構築されたクエリ文字列はRFC 3986エンコード(+ = リテラルプラス)を使用する場合があります。ほとんどのサーバーフレームワークはクエリ文字列にフォームエンコードを想定するため、値のリテラルの+は%2Bとして送信すべきです。
ユースケース
POSTリクエストでのHTMLフォームデータの送信、OAuth署名ベース文字列の構築、フォームエンコードペイロードを期待するAPIへのデータ送信。