URLエンコーディング完全ガイド
URLエンコーディングについて知っておくべきことをすべて学びましょう。URLエンコーディングとは何か、なぜ重要なのか、パーセントエンコーディングの仕組み、そしてURL内の特殊文字を扱うためのベストプラクティスを解説します。
URLエンコーディングとは
URLエンコーディング(パーセントエンコーディングとも呼ばれます)は、特定の状況下で統一資源識別子(URI)に情報をエンコードするための仕組みです。URLエンコーディングという名前で知られていますが、実際にはより広く、統一資源位置指定子(URL)と統一資源名(URN)の両方を含む統一資源識別子(URI)全般で使用されます。
このエンコーディングが必要になるのは、URLがインターネット上でASCII文字セットを使ってしか送信できないためです。URLにはASCII以外の文字が含まれることが多いため、URLを有効なASCII形式に変換する必要があります。URLエンコーディングでは、安全でないASCII文字を%とそれに続く2桁の16進数に置き換えます。
パーセントエンコーディングの仕組み
パーセントエンコーディングの仕組みは、エンコードが必要な各文字を1つ以上のバイトに変換することで動作します。そして各バイトは、パーセント記号とそれに続く2桁の16進数で表現されます。この16進数は、指定されたエンコーディング(通常はUTF-8)における文字のバイト値を表します。
たとえば、スペース文字(ASCII値32、16進数20)は%20になります。アンパサンド&(ASCII値38、16進数26)は%26になります。アキュートアクセント付きのeのようなASCII以外の文字は、まずUTF-8のバイト列にエンコードされ、その後各バイトがパーセントエンコードされます。
予約文字と非予約文字
RFC 3986では、URIで使う文字を予約文字と非予約文字の2つのカテゴリに定義しています。非予約文字には、大文字と小文字のアルファベット(A-Z、a-z)、数字(0-9)、ハイフン(-)、ピリオド(.)、アンダースコア(_)、チルダ(~)が含まれます。これらの文字はエンコードせずにURIに含めることができます。
予約文字はURL構文において特別な意味を持ちます。これには次の文字が含まれます。:、/、?、#、[、]、@、!、$、&、'、(、)、*、+、,、;、=。これらの文字を本来の予約された用途以外でURIコンポーネント内に使用する場合は、パーセントエンコードしなければなりません。
さまざまな言語でのURLエンコーディング
JavaScript
JavaScriptはURLエンコーディング用に2組の関数を提供しています。完全なURIをエンコードするためのencodeURI() / decodeURI()と、個々のURIコンポーネントをエンコードするためのencodeURIComponent() / decodeURIComponent()です。両者の重要な違いは、encodeURI()がURIで特別な意味を持つ予約文字(/、?、#など)をそのまま保持するのに対し、encodeURIComponent()は英数字以外のすべての文字をエンコードする点です。
Python
Pythonのurllib.parseモジュールは、基本的なエンコード/デコードを行うquote()とunquote()に加え、辞書をクエリ文字列にエンコードするurlencode()を提供しています。quote()関数はオプションのsafeパラメータを取り、エンコードすべきでない文字を指定できます。
PHP
PHPには、スペースを+としてエンコードする(application/x-www-form-urlencoded形式に従う)urlencode()と、スペースを%20としてエンコードする(RFC 3986に従う)rawurlencode()があります。デコードには、それぞれurldecode()とrawurldecode()を使用します。
ベストプラクティス
- URLに含める前に、必ずユーザー入力をエンコードする
- JavaScriptでクエリパラメータの値をエンコードするには
encodeURIComponent()を使用する encodeURI()は完全なURIをエンコードする場合にのみ使用する- アプリケーション全体を通してエンコーディングの方針を一貫させる
- 処理する前に、サーバー側で必ずURLをデコードする
- Unicodeを含む特殊文字でエンコーディングをテストする
- URLを二重エンコードしない。文字列がすでにエンコードされていないか必ず確認する