URLパスエンコードとクエリ文字列エンコードの違い
URLパスセグメントエンコードとクエリ文字列エンコードの違いを解説。各コンテキストで安全な文字と、区別が重要な理由を理解しましょう。
詳細な説明
URLパスとクエリ文字列は、異なる構造的目的を持つため異なるエンコードルールがあります。パスで安全な文字がクエリ文字列ではエンコードが必要な場合や、その逆もあります。これらの違いを理解することは、正しいURLを構築するために不可欠です。
URLの構造:
https://example.com/path/segment?key=value&key2=value2#fragment
|-- パス ---|--- クエリ文字列 -----|--フラグ--|
パスエンコードのルール:
- スラッシュ
/はセグメント区切り(エンコードしない) - コロン
:は許可される(ただし曖昧な場合がある) @はパスセグメントで許可される+はリテラルのプラス記号であり、スペースではない- 各パスセグメントを
encodeURIComponent()で個別にエンコードし、/で結合する
クエリ文字列エンコードのルール:
&がパラメータを区切る(値に含まれる場合はエンコード)=がキーと値を区切る(値に含まれる場合はエンコード)+はスペースを表す(フォームエンコードの場合)?はクエリ文字列の区切り(値に含まれる場合はエンコード)
JavaScriptでのアプローチ:
// 動的セグメントを含むパスの構築
const userName = "John Doe/Admin";
const pathSegment = encodeURIComponent(userName);
const path = `/users/${pathSegment}/profile`;
// "/users/John%20Doe%2FAdmin/profile"
// クエリ文字列の構築
const params = new URLSearchParams({ user: "John Doe/Admin" });
const query = params.toString();
// "user=John+Doe%2FAdmin"
// 両方を組み合わせる
const fullUrl = `https://example.com${path}?${query}`;
主な違いのまとめ:
| 文字 | パス内 | クエリ値内 |
|---|---|---|
| スペース | %20 |
%20または+ |
/ |
区切り(エンコードしない) | %2F |
+ |
リテラルプラス記号 | スペース(フォームエンコード)または%2B |
? |
%3F |
クエリ開始(値ではエンコード) |
& |
許可される | パラメータ区切り(値ではエンコード) |
= |
許可される | キーバリュー区切り(値ではエンコード) |
@ |
許可される | %40 |
: |
許可される | %3A |
よくある間違い: パスとクエリコンポーネントの両方に同じエンコード関数を使用すること。パスでは個々のセグメントをencodeURIComponent()でエンコードしつつ、セグメント間の/区切りを保持します。クエリ文字列では個々のキーと値をエンコードします。URL全体を一度にエンコードしてはいけません。
落とし穴: +文字はパスとクエリで異なる動作をします。パスでは/search/c++にはリテラルの++が含まれます。クエリでは?lang=c++はフォームエンコードのルールによりlang=c (スペース2つ)と解釈されます。クエリ値でリテラルの+が必要な場合は、常に%2Bとしてエンコードしてください。
ユースケース
動的パスパラメータとクエリフィルタを含むREST API URLの構築。URL内の位置に応じて各コンポーネントが正しくエンコードされることを保証する。