URLのパーセントエンコーディング:%20・+・%2Fの意味
パーセントエンコーディングは、URLに安全に入れられない文字を、パーセント記号と、その文字のバイト値を16進数で書いたものに置き換える方法です。空白は%20、アンパサンドは%26、スラッシュは%2Fになります。&や=のような文字はクエリ文字列の各部分を区切るため、エンコードによってリンクの構造を守っています。
そのままで使える文字
URLの基になっているURI標準(RFC 3986)では、A〜Zとa〜z、数字、そして- _ . ~の4つの記号はそのまま使えます。これらは決してエンコードする必要がありません。それ以外の文字はURL内で役割を持っています。コロンはスキームと残りを区切り、スラッシュはパスの部分を区切り、疑問符はクエリの始まり、ハッシュはフラグメントの始まりを示し、&と=はクエリを名前と値に分けます。役割を持つ文字は、データとして使う場合はエンコードしなければなりません。
そのため、同じ文字でも場所によってエンコードが必要だったり不要だったりします。クエリの値の中では、アンパサンドは%26にしなければ、リンクが間違った場所で分割されてしまいます。リンクのパスの中では、ただの文字にすぎません。
英語以外の文字
基本的な英字以外の文字は、UTF-8のバイト列にして、各バイトをパーセントコードで書きます。café の é は、C3とA9の2バイトなので%C3%A9になり、単語全体はcaf%C3%A9になります。
簡単な例でルールを確かめてみましょう。文字列a b&c=d/éをコンポーネントとしてエンコードすると、a%20b%26c%3Dd%2F%C3%A9になります。安全な文字、数字、記号以外のすべての文字がエンコードされます。空白、アンパサンド、等号、スラッシュ、アクセント付きの文字がそれにあたります。
コンポーネントかURL全体か
エンコードには2種類あり、それぞれ理由があります。コンポーネントエンコードは、予約された文字をすべてデータとして扱います。検索語や、リンク内のファイル名など、1つの値に使います。「rock & roll」を検索語としてエンコードするとrock%20%26%20rollになり、アンパサンドは値の中に残ります。
URL全体のエンコードは、構造を保ったままにします。https://example.com/a bをエンコードするとhttps://example.com/a%20bになり、スラッシュとコロンはそのままです。リンクの中に入れる値ではなく、有効な形に直す必要がある完全なアドレスに使います。
URLエンコード・デコードには、この違いのためにコンポーネントとURL全体の設定があります。URL全体のデコードでは、%26や%3Dのようにエスケープされた構造上の文字も残るため、デコード後もリンクが機能します。
プラス記号とフォームのデータ
Webフォームは別の決まりを使います。フォームのデータとして送信される場合、空白は%20ではなく+で書かれます。そのため、プラス記号そのものは%2Bになります。たとえば「C++ tips」という文字列は、フォームのデータではC%2B%2B+tips、通常のコンポーネントエンコードではC%2B%2B%20tipsになります。
デコードでも同じ違いがあります。クエリ文字列では、+は通常、空白を意味します。リンクのパスの中では、+はプラス記号です。ツールは「+を空白として扱う(フォームデータ)」にチェックが入っているときだけ+を空白として読むので、パスや、プラス記号が実際の文字である値では、チェックを外したままにしてください。
長いクエリ文字列の読み方
リンクは、疑問符の後ろに設定を入れることがよくあります。次の例を見てください。
https://shop.example/search?q=red%20shirt&size=M&tag=summer%2Bsale
デコードすると、検索語は red shirt、サイズは M、タグは summer+sale であることが分かります。%2Bはエンコードされていたため、プラス記号のまま残ります。リンクをURLエンコード・デコードに貼り付けると、デコード後の各名前と値が一覧表示されるので、長いリンクも読みやすくなります。トラッキング用の設定を除いた短いアドレスだけが欲しい場合は、先にリンクのクリーナーを使ってください。
二重エンコード
最もよくある間違いは、値を2回エンコードすることです。文字列%20をもう一度エンコードすると%2520になります。パーセント記号自体が%25にエンコードされるためです。するとページは値の中に%20という文字列を探すため、検索結果が一致しなかったり、ページが正しく表示されなかったりします。リンクは1回デコードして結果を確認し、本当に必要なときだけ値をエンコードしてください。
壊れたエスケープ
パーセント記号の後ろには、必ず16進数の数字が2つ続かなければならず、アクセント付きの文字では、その数字がUTF-8として正しい並びになっている必要があります。途中で切れたリンクや、文章に誤って入ったパーセント記号は、%E0%A4%Aのような壊れたエスケープを残すことがあります。ツールはデコードできる部分をデコードし、壊れたバイトはそのまま残して、デコードできなかった数を表示します。最初のエラーで処理を止めることはありません。
特殊なケース
- 手で入力したリンクの空白。 ブラウザのアドレスバーは空白を自動でエンコードしますが、文書にコピーされたリンクには、エンコードされていない空白が残ることがあります。送る前にエンコードしてください。
- 英語以外のドメイン名。 これらはpunycodeという別の仕組みを使います。パスやクエリをエンコードしても、ホスト名は変わりません。
- 絵文字の半分。 壊れたコピーでは、サロゲートの片方だけが残ることがあり、これはエンコードできません。ツールはそれを置換文字に置き換え、置き換えたことを知らせます。
- リンク内のBase64。 リンク内のBase64の値は独自の規則に従い、+と/の代わりに-と_を使います。Base64の解説を参照してください。
fixmintでの使い方
- テキストまたはリンクをテキストまたはURLに貼り付けます。
- エンコードまたはデコードを選び、1つの値ならコンポーネント、アドレス全体ならURL全体を選びます。
- Webフォームからコピーしたリンクなら、「+を空白として扱う(フォームデータ)」にチェックを入れます。
- リンクの場合は、デコード後のクエリパラメータを見ると、各名前と値を確認できます。
- 結果をコピーします。
よくある質問
%20は何を意味しますか?
空白です。そのバイト値は16進数で20です。
リンクに%20ではなく+があるのはなぜですか?
そのリンクはフォームから来たものと思われます。フォームでは+が空白を表します。「+を空白として扱う(フォームデータ)」オプションでデコードできます。
リンクに%2520が表示されるのはなぜですか?
値が2回エンコードされています。%20のパーセント記号が、%25としてもう一度エンコードされたのです。1回デコードすると%20に戻り、もう1回デコードすると空白になります。
英語原文をもとに、AIの支援を受けて翻訳しています。
コメント
まだコメントはありません。最初のコメントを書いてみましょう。


