URLエンコードとパーセントエンコーディングの仕組み
このツールができること
URLが安全に運べる文字は限られています。予約されていない英数字といくつかの記号を除いた文字はすべて、パーセントエンコーディング(%記号のあとに16進数のバイト値が続く形式)に書き換える必要があります。このツールは通常のテキストをそのエンコード形式に変換し、逆方向にも動作して、%20や%26といった並びを元の文字に戻します。
実際に出会う場面は、2つのエンコード方式でカバーできます。標準エンコードはJavaScriptのencodeURIComponentを使い、英数字と - _ . ! ~ * ' ( ) 以外のすべての文字をエスケープします。:、/、?、#、& といった構造上の文字も含まれるので、パラメータの値のような単独の部分に向いています。フォームエンコードは、ブラウザがフォームを送信するときに使うapplication/x-www-form-urlencodedの規則に従い、スペースを%20ではなく+として書きます。
使いどころ
値をクエリ文字列の中に入れるときは、標準エンコードを選びます。検索語、メールアドレス、あるいはそれ自体に?、&、=を含むリダイレクト先などです。エンコードしておけば、これらの記号がURLの構造として読まれてリンクが壊れることを防げます。構造上の文字はすべてエスケープされるため、アドレスは部分ごとに別々にエンコードしてください。完成したURLをまるごとエンコードするとスラッシュや疑問符までエスケープされ、それが正しいのは、そのURLが別のURLの中の値である場合だけです。フォームエンコードは、POSTリクエストの本文や手作業で組み立てたフォームの値に対応し、スペースは%20ではなく+として書かれます。デコードも同じくらいよく使います。ログやアクセス解析レポート、リダイレクトの連鎖から拾ったエンコード済みリンクを貼り付け、実際にどこを指しているのかを読み解く場面です。
具体例
hello world & café というテキストで考えます。標準エンコードでは、スペースは%20に、アンパサンドは%26になり、café は é がUTF-8で2バイトとして格納されるため caf%C3%A9 になります。フォームエンコードでは、同じスペースが+として書かれ、hello+world となります。要約の1行には、何文字が変化し、それがテキスト全体のどれくらいにあたるかが表示されます。
注意点とエッジケース
予約文字(: / ? # [ ] @ ! $ & ' ( ) * + , ; =)はURLの中で意味を持ちます。どちらの方式も : / ? # [ ] @ $ & + , ; = をエスケープし、! ' ( ) * はそのまま残すので、エンコードするのは完成したURLではなく、クエリ文字列に入れる値にしてください。エンコードはUTF-8のバイト列を基準に定義されているので、ASCII以外の文字は複数の%XXの並びに展開されます。URLを二重にエンコードしないよう注意してください。すでにエスケープの一部になっている%が%25に変わると、リンクは解決しなくなります。迷ったときは、まずデコードして、テキストが素の状態か、すでにエスケープ済みかを確かめましょう。