レッスン 5

フォームデータにおけるプラス記号

クエリ文字列で `+` がスペースを意味することがある理由と `%20` vs `+`。

URL 内のスペースは歴史的に問題だったため、デフォルト HTML <form method="GET"> が使う application/x-www-form-urlencoded は、シリアライズ body またはクエリ部分文字列でスペースを + としてエンコードします。

<form>
  <input name="msg" value="hello world">
</form>
<!-- 送信 URL に ?msg=hello+world が含まれることがある -->

これはすべてのツールパスで汎用 URI percent エンコードと同じルールではありません: 多くの URI プロセッサーは、form-urlencoded 意味論を明示しない限り + をリテラル plus として扱います。

?msg=a+b           // パーサーモード次第で "a b" または "a+b"
?q=city%20hall     // ASCII スペースの明確な URI percent エンコード (%20)

JavaScript ヘルパー

URLSearchParams

const p = new URLSearchParams("a=b+c");
console.log(p.get("a")); // フォームモードでは '+' をスペースと解釈しがち

オブジェクトから作成すると stringify 時にフォームルールを保持:

new URLSearchParams({ tag: "a+b" }).toString(); // '+' 向けに a%2Bb や tag=a%2Bb パターン(内部実装次第)
console.log(String(new URLSearchParams({ expr: "1+2" })));

相互運用可能なリテラルが必要なら、plus を plus のまま残す必要がある場合は明示的に percent エンコード(%2B)。

手動デコードのミス

decodeURIComponent だけでは percent シーケンスのみ想定 — '+' は変換しない:

decodeURIComponent('a+b');           // "a+b" のまま
decodeURIComponent('a+b'.replace(/\+/g, " ")); // 手動フォーム型修正 — 層が正しいときのみ

サーバーフレームワーク

人気スタックはトグルを公開(application/x-www-form-urlencoded パーサー vs 生クエリパーサー)。ミドルウェア順序が重要:

  1. URI コンポーネント意味論でクエリをパース。
  2. + → スペースルール付き HTML フォーム意味論でパース。

誤設定は、環境間で '+' の意味が変わりハッシュトークンが壊れるなどのバグを生みます。

何をいつエンコードするか

必要推奨
URL を跨ぐフォームフィールド値のリテラル '+'値層で %2B をエンコード
JSON 輸送の人間可読 '+'クエリより JSON body を優先
デバッグログパーサーが書き換える前の生バイトreq.url)を捕捉

+ を理解すると、二重デコード、パーサー不一致、本当に %2B が必要なユーザー入力、のバグ分類に役立ちます。レッスン 4 の部分デコード後の脆い split('&') 警告と組み合わせてください。

実践したいときは関連する DevCove ツールを使えます。任意であり、このレッスンの必須部分ではありません。

関連ツールを開く

コース概要へ戻る