コンテンツへスキップ

URLエンコード

テキストをパーセントエンコードして、URLの中でも崩れないようにします。3つの用途に3種類のエンコードがあり、選び間違えると値が気づかないうちに壊れます。そこで、どれが必要かをページが教えます。

  • 保存しません
  • 順番待ちなし
  • 登録不要・透かしなし
エンコード結果

ここにエンコード結果が表示されます。

使い方

1

テキストを貼り付け

どんな言語のどんなテキストでも。最新のサーバーがすべて想定しているUTF-8としてエンコードします。

2

用途を選ぶ

クエリ文字列に入れる1つの値、組み立て済みのURL全体、またはフォームの送信。違いは重要で、それぞれ説明しています。

3

結果をコピー

まとめて処理したいリストがあれば、1行ずつエンコードできます。

正しい答えが3つあり、ボタン1つでは間違う理由

パーセントエンコーディングは、文字を % とそのバイト値の16進数に置き換えます。仕様は文字を3つのグループに分けており、分かりにくさはすべてそこから生じています。非予約文字(英字、数字、ハイフン、ピリオド、アンダースコア、チルダ)はエンコードする必要がありません。予約文字(URLの構造を作るスラッシュ、疑問符、アンパサンド、等号、コロン)は、*データであるときは*エンコードしなければならず、*構造であるときは*エンコードしてはいけません。それ以外はすべて常にエンコードします。

だからこそ、唯一の正解はありません。 URL全体をエンコードするなら、スラッシュや疑問符はそのままにしなければ、アドレスがアドレスでなくなります。クエリパラメーターに入れる値をエンコードするなら、アンパサンドと等号をエスケープしなければ、それを含む値が2つのパラメーターに分かれてしまいます。パスのセグメントをエンコードするなら、スラッシュをエスケープしなければ、スラッシュを含むファイル名が2つのディレクトリになってしまいます。「エンコード」ボタンが1つだけなら、このうち1つを選ぶことになり、残りの3分の2のケースでは間違えます。たいていは気づかれないまま、そして珍しい入力のときにだけ表に出る形で。

最も多くの経緯を背負っている文字がスペースです。URLの中では %20 です。HTMLフォームで送信されると + になります。これは別の古いエンコード方式で、フォームが1994年からそう動いてきたために残っています。どちらもそれぞれの文脈では正しく、もう一方の文脈では正しくありません。クエリ文字列の中のプラス記号が曖昧になるのはそのためで、これはエンコードする側がいくら気を付けても解決できません。

ASCII以外のテキストはまずUTF-8にエンコードしてから1バイトずつエンコードするため、アクセント付きの1文字は2つ、絵文字は4つのパーセントシーケンスになります。典型的なバグが二重エンコードです。すでにエンコード済みのものをエンコードするとすべての % が %25 になり、%20は%2520になって、受け取る側には%記号がそのまま届きます。URLに%25がたくさん含まれていたら、エンコーダーを1回余計に通っています。

ほかの目的には

コードでは、言語に用意された関数を使い、このページで選ぶのと同じくらい意識して選んでください。JavaScriptにはアドレス全体用の encodeURI と値用の encodeURIComponent があります。Pythonの urllib.parse.quote には、デフォルトでスラッシュをそのまま残す safe 引数があります。PHPは rawurlencode と urlencode を区別しており、両者の違いはまさに上で述べたスペースかプラスかの問題です。さらに良いのは、文字列をつなげるのではなくURL型を使ってURLを組み立てることで、そうすればこの問題自体がなくなります。

コマンドラインでは、jq -rR @uri が安全にエンコードでき、リストも扱えます。curl --data-urlencode は、3つのうちどのケースかを考えなくても正しくエンコードしたパラメーターを組み立ててくれます。これが本当に簡単に済む唯一の場面です。

よくある質問

3つのうちどれを使えばよいですか?

ほとんどの場合は「1つの値」です。検索語、メールアドレス、リダイレクト先など、クエリ文字列やパスのセグメントに入れようとしている「1つの」値をエンコードするときに使います。3つのうち&、=、?、/をエスケープするのはこれだけで、それこそが、値がパラメーターからはみ出して2つのパラメーターになるのを防ぎます。「URL全体」は、すでに完成したURLがあり、安全でない文字だけを整えたいときにだけ使ってください。URLとして機能し続けるよう、構造を作る文字を意図的にそのまま残します。「フォームデータ」は、スペースが%20ではなく+になるapplication/x-www-form-urlencodedのボディを組み立てるときに使います。

なぜ「&」でURLが壊れたのですか?

エンコードされていなかったからです。&はクエリ文字列でパラメーターを区切るための文字です。「Smith & Sons」という値を?company=の後にそのまま付けると、サーバーにはcompany=Smithと、「Sons」という名前の空のパラメーターが届きます。最もよくあるURLのバグで、直すには「1つの値」のエンコードを使います。&を%26に変えるので、値は1つの値のまま保たれます。

なぜ「+」がスペースになったのですか?

クエリ文字列では+がスペースを意味するからです。HTMLフォームから受け継がれた規則で、誰にも取り除けないまま残っています。そのため、電話番号やBase64の文字列など、データに含まれるプラス記号は、受け取るサーバーにスペースとして読まれます。「1つの値」のエンコードなら%2Bにエスケープされ、そのまま届きます。

ほかの言語や絵文字にも対応していますか?

はい。テキストをまずUTF-8に変換してから1バイトずつパーセントエンコードします。これはRFC 3986が求める方法で、最新のサーバーがすべて想定しているものです。日本語、アラビア語、アクセント付きのラテン文字、絵文字はどれも、エンコードしてデコードすると正確に元どおりになります。

ほかのツールではそのままの ! ' ( ) * が、なぜここではエンコードされるのですか?

ブラウザ標準のencodeURIComponentはこの5文字をそのまま残しますが、RFC 3986では予約文字とされているからです。これらを構造の一部として扱うサーバーやフレームワークもあり、これらを含む値が誤って読まれることがあります。エンコードしても害はなく、どこでも元どおりにデコードされます。そして、まれで原因を突き止めにくい種類のバグを取り除けます。慎重な実装はこうしています。

テキストはどこかに保存されますか?

いいえ。何も保存されず、通信も行われません。ページを読み込んだ後はインターネットを切断しても動作します。

ご注意: 正しい答えは3種類あり、このページでは選んでもらいます。よくある「エンコード」ボタン1つでは、3回に2回は間違うからです。URL全体、クエリパラメーター、パスのセグメントのエンコードでは、エスケープする文字が異なります。間違ったものを使うと、スラッシュ、プラス記号、アンパサンドが気づかないうちに壊れます。

このツールをあなたのサイトに設置

ブログ、授業のページ、ヘルプ記事などに無料で設置できます。コードを1つ貼り付けるだけで、訪問者がそのページ上でツールを使えるようになります。