レッスン 4
クエリ文字列とパラメータ
`?key=value&` ペアを正しく構築・パースする。
http(s) URL の最初の ? 以降がクエリコンポーネント — 多くのブラウザとサーバーフレームワークが、たとえ HTML フォームでなくても application/x-www-form-urlencoded 形式のペアとして解釈します。
https://api.example.com/items?tag=book&sort=price_asc&page=2
パースすると 3 キー: tag、sort、page。
ペア構文
- ペアは
&で区切る(歴史的に;も野生トラフィックに現れるが、明示サポートなしでは非推奨)。 - ペア内、最初の
=が名前と値を区切る:flag→ 多くのパーサーで空文字列値q=→ 空値q=ruby+gems→ フォームルールではリテラル plus がスペースを意味しうる(レッスン 5 参照)。
?q=hello&empty=&flag
キー繰り返しはワイヤー形式では許可:
?tag=a&tag=b
解釈(最後を残す vs 配列収集)はフレームワーク依存 — 決め打ちしない。
連結前に値をエンコード
値に &、=、#、非 ASCII テキストが含まれるなら、結合前にコンポーネントをエンコード:
const base = "https://example.com/search";
const params = new URLSearchParams({ q: "fish & chips", city: "São Paulo" });
const url = `${base}?${params.toString()}`;
URL で区切り文字を健全に保つ:
const url = new URL("https://example.com/search");
url.searchParams.set("q", "100% completion");
console.log(url.toString());
パースの落とし穴
手動 split('&') は、デコード後の値内に stray & があると失敗:
// デコードで余分な & が現れるまで問題なさそう
decodeURIComponent('a=b%26c=d')
URL(searchParams)、サーバーライブラリ、または部分デコード後の単純 split ではなく正しい状態でバイトを反復するパーサーを優先。
相対 URL と HTML コンテキスト
アンカー <a href="..."> はドキュメントベースに対して相対 URL を解決:
<a href="?page=2">Next</a>
絶対パスを期待していた場合に驚く — 解決順序(scheme → host → path → クエリ追加ルール)を理解する。
順序と正規化
署名付き URL やキャッシュはパラメータ順序を重要視することがある。署名用文字列生成では、キーをソートするか、percent エンコード方法を定義 — AWS 型署名や OAuth 1.0 型 string-to-sign は、カジュアルなブラウザ動作を超える厳格な正規化の典型。
クエリ文字列の習得は、コンポーネント境界とスタック各層の適切なエンコード層の選択が中心です。