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内の位置に応じて各コンポーネントが正しくエンコードされることを保証する。

Try It — URL Encoder

フルツールを開く