URL をデコードする方法
- エンコードされたテキストを エンコード済みの URL またはテキスト に貼り付けます。
- クエリ文字列やフォームデータでは + を空白として扱う をオンのままにし、パスや Base64 の値ではオフにします。
- 結果にまだ
%XXが含まれている場合はステータスに案内が出るので、繰り返しデコード にチェックを入れます。 - ログファイルや値の列を扱う場合は 1 行ずつ処理 にチェックを入れると、各行が個別にデコードされます。
- 元データが UTF-8 でなければ 文字コード を選び、出力をコピー します。
入力が完全な URL の場合、入出力欄の下の表に、スキーム、ホスト、デコード済みのパス、1 行に 1 つずつのクエリパラメータ、フラグメントが表示されます。長いトラッキング URL やリダイレクト URL を読むにはこれが一番手早い方法です。
例
| エンコード済み | デコード後 | 補足 |
|---|---|---|
q=base64%20%26%20%22url-safe%22 | q=base64 & "url-safe" | %26 は &、%22 は " |
lang=%E6%97%A5%E6%9C%AC%E8%AA%9E | lang=日本語 | UTF-8 では 1 文字 3 バイト |
%F0%9F%98%80 | 😀 | 絵文字は 4 バイト |
q=a+b%2Bc | q=a b+c | + を空白として扱う を使用 |
next=%252Fhome%253Ftab%253D1 | next=/home?tab=1 | 二重エンコード、2 回 |
caf%E9 | café | UTF-8 ではなく Windows-1252 または ISO-8859-1 |
二重エンコード
エンコード済みの文字列をさらにエンコードするたびに、% はすべて %25 になります。そのため / は %2F、%252F、%25252F と変わっていきます。リダイレクト URL が複数のサービスを経由したときや、コードがすでにエンコードした値をフレームワークがもう一度エンコードしたときに起こります。
こうした文字列を読むには、エスケープがなくなるまでデコードします。繰り返しデコード がそれを行い、回数を表示します。原因を直すには、2 回目のエンコードをしている層を見つけてください。別の URL を保持する next= や url= パラメータのように、正当に入れ子になった URL では、追加の層はちょうど 1 つで、それ以上にはなりません。
こうした入れ子のよくある発生源は、メールのセキュリティゲートウェイです。Microsoft Defender の Safe Links の URL は https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fexample.com%2Freset%3Fid%3D42&data=… のような形をしています。貼り付ければ、何もクリックせずに、パラメータ表で本当のリンク先 https://example.com/reset?id=42 を確認できます。
不正なエスケープとレガシー文字コード
% の後にはちょうど 2 桁の16進数が必要です。100%、%zz、エスケープの途中で切れた URL はエラーで、デコーダーは「位置 N のエスケープが壊れています」と報告します。JavaScript の decodeURIComponent は同じ場合に URIError: URI malformed を投げ、Python の unquote はそのシーケンスをそのまま残します。
もう一つのエラーの原因は文字コードです。パーセントエスケープはバイトを表し、%E9 単独では有効な UTF-8 ではありません。Python はこれを置換文字としてデコードし、JavaScript は例外を投げます。文字コード を Windows-1252 や ISO-8859-1 にすれば é にデコードされます。Shift_JIS、GBK、EUC-KR、KOI8-R などのレガシー文字コードも同じリストにあります。
コードでの URL デコード
decodeURIComponent("a%20b%26c") // "a b&c"
new URLSearchParams("q=a+b%2Bc").get("q") // "a b+c"
from urllib.parse import unquote, unquote_plus, parse_qs
unquote("caf%C3%A9") # 'café'
unquote("caf%E9", encoding="latin-1") # 'café'
unquote_plus("q=a+b%2Bc") # 'q=a b+c'
parse_qs("q=a+b%2Bc&tag=x&tag=y") # {'q': ['a b+c'], 'tag': ['x', 'y']}
decodeURIComponent は + をスペースに変えませんが、URLSearchParams と unquote_plus は変えます。文字列がどう作られたかに合わせて選んでください。エンコードについては URL エンコーダー を、URL を経由して届いた Base64 については Base64URL デコーダー を参照してください。
よくある質問
URL エンコードされた文字列をデコードするには?
上に貼り付ければ、入力に合わせてデコード結果が表示されます。JavaScript なら decodeURIComponent(s)、Python なら urllib.parse.unquote(s) を使います。+ がスペースを表す場合は unquote_plus(s) です。
デコードした URL にまだ %20 や %3A が残っているのはなぜですか?
二重にエンコードされているからです。1 回目で %2520 が %20 になり、2 回目でスペースになります。繰り返しデコード にチェックを入れると、エスケープがなくなるまで最大 5 回デコードを続け、何回かかったかを表示します。
decodeURIComponent が URI malformed を投げるのはなぜですか?
100% のように % の後に16進数 2 桁が続いていないか、Windows-1252 のシステムから来た %E9 のようにバイト列が有効な UTF-8 ではないかのどちらかです。このデコーダーは正確な位置を示し、文字コード オプションでレガシーなエンコードもデコードできます。
+ はスペースとしてデコードすべきですか?
クエリ文字列とフォームボディの中ではそうです。そのため + を空白として扱う はデフォルトでオンになっています。URL のパスや Base64 を含む可能性のある値では、+ は文字どおりのプラス記号なのでチェックを外してください。