パーセントエンコーディング

URL で特殊文字を %XX 形式の 16 進数で表現するエンコーディング方式。URL エンコーディングとも呼ばれる。

パーセントエンコーディング (Percent-Encoding) は、URL 内で使用できない文字や特殊文字を % に続く 2 桁の 16 進数で表現するエンコーディング方式です。URL エンコーディングとも呼ばれ、RFC 3986 で標準化されています。Web の基盤技術として、ブラウザとサーバー間の通信で非 ASCII 文字や予約文字を安全にやり取りするために不可欠な仕組みです。

エンコーディングの仕組みはシンプルです。対象の文字を UTF-8 でバイト列に変換し、各バイトを % + 2 桁の 16 進数で表現します。たとえば半角スペースは %20 (0x20)、日本語の「あ」は UTF-8 で 3 バイト (0xE3, 0x81, 0x82) なので %E3%81%82 となります。RFC 3986 では非予約文字 (A-Z, a-z, 0-9, -, _, ., ~) 以外のすべての文字にパーセントエンコーディングが必要と定められています。Web 開発基礎の書籍で URL エンコーディングの詳細を学べます。

実務では、検索クエリやフォームデータの送信時にブラウザが自動的にパーセントエンコーディングを適用します。JavaScript では encodeURIComponent() でエンコード、decodeURIComponent() でデコードを行います。一方、encodeURI() は URL 全体を対象とし、/? などの予約文字はエンコードしません。この 2 つの関数の使い分けを誤ると、URL が壊れたりセキュリティ上の問題が生じたりするため注意が必要です。

よくある誤解として、パーセントエンコーディングと HTML エンティティ (& など) を混同するケースがあります。パーセントエンコーディングは URL 専用の仕組みであり、HTML 内の特殊文字のエスケープとは目的も構文も異なります。また、日本語 URL を扱う際は、ブラウザのアドレスバーが表示上はデコードして見せている点にも注意しましょう。実際の HTTP リクエストではエンコード済みの URL が送信されています。

類似の概念として Base64 エンコーディングがありますが、用途が異なります。パーセントエンコーディングは URL 内の個々の文字を安全に表現するためのもので、Base64 はバイナリデータをテキスト形式に変換するためのものです。また、application/x-www-form-urlencoded 形式ではスペースを %20 ではなく + で表現するなど、コンテキストによる差異も存在します。HTTP プロトコル解説の書籍で URL の構造とエンコーディングが詳しく解説されています。

文字数カウントの観点では、パーセントエンコーディングは元の文字数と URL 上のバイト数の乖離を生みます。日本語 1 文字が UTF-8 で 3 バイト、パーセントエンコーディング後は 9 文字 (%XX%XX%XX) に膨張します。URL の長さ制限 (多くのブラウザで約 2,000 文字) を考慮する際、日本語を含むクエリパラメータがどの程度の長さになるかを事前に見積もることが重要です。