レッスン 2

パーセントエンコードのルール

`%XX` がバイトを表す仕組みと、エンコードが必要な文字。

パーセントエンコードは、エスケープする各オクテットに % とちょうど 2 桁の 16 進数を書きます。

byte 32 (space)  → %20
byte 38 (&)       → %26
byte 231 (decimal) → hex E7 → %E7   (意味はデコードコンテキスト次第!)

A–F は大文字小文字どちらも可(%e7%E7)。ツールは一貫した方が相互運用しやすいが、パーサーは混在を受け入れるべき。

1 エスケープ = 1 バイト(「1 UTF-16 コードユニット」ではない)

Unicode 文字列をエンコードするとき、スキームが別途定めない限り UTF-8 のオクテットをエンコード:

π (U+03C0)

UTF-8 bytes: CF 80  → %CF%80
誤ったメンタルモデル: コードポイント桁 "03C0" を hex でエンコード
正しいモデル: 先にバイト列化し、問題のある各バイトを %HH

どのバイトをエスケープするか

おおよそのチェックリスト:

  1. URI 区切りと相互作用するグラフィック文字?, &, #, /, :, @, [, ])で、それらが句読点ではなく不透明データに属するとき。
  2. ASCII 外のバイト(広い互換パス向け)。
  3. 制御バイト、スペース、DEL、曖昧な空白(パラメータ内のリテラルデータとして)。

RFC 3986 は汎用ルールと正規化動作を定義; フレームワークは厳格化することがある(例: stray % 尾を禁止)。

無効なエスケープ

不完全シーケンスはパーサーを混乱させる:

%           → 不正(桁なし)
%AB         → 不正(2 ニブル必要)
%GG         → 無効な hex 桁

良いライブラリは不正入力を検証または拒否し、黙って「最善推測」しない。

過剰エンコードと二重エンコード

percent エンコードを 2 回適用するのは繰り返しバグ:

literal value: 100%

first pass:    100%25     (リテラル % が %25 に)
mistaken pass: 100%2525   (既に安全な % を再エンコード — 表示意図と違う)

サーバーが %2525 を受け取ると、2 回デコードして単一 % — 表示データの意図ではない。サブシステムがエンコード済みかデコード済みか一度決め、その不変条件を明確に。

正規化のヒント

正規化には次の選択が含まれる:

  • 16 進の大文字 vs 小文字(どちらも有効)。
  • コンポーネント内で法的に曖昧でないとき、句読点をエンコードするかリテラルに残すか。
  • エンコード前に Unicode を NFC に正規化(任意だが、綴り重複でサーバーが分岐するのを避ける)。

ゲートウェイ(CDN vs アプリ vs DB)間で一貫性を保ち、署名検証やキャッシュ中の微妙な不一致を避ける。

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

関連ツールを開く

コース概要へ戻る