App Museum
English

URLエンコードで特殊文字を正しく扱う方法

URL全体とクエリ値を区別し、空白、プラス、パーセントなどを二重エンコードせず安全に変換・確認する手順を解説します。

公開日: 2026-08-10 · 更新日: 2026-08-10

URL全体と値を分けて考える

URLにはスキーム、ホスト、パス、クエリ、フラグメントなど、役割の異なる部分があります。URL全体を一つの値としてエンコードすると、https://:/、クエリを始める ? まで変換され、そのまま移動先URLとして使えなくなります。

たとえば検索語 red + blue & 50%q の値として渡す場合、エンコードする単位は検索語だけです。

input value: red + blue & 50%
encoded value: red%20%2B%20blue%20%26%2050%25
complete URL: https://example.com/search?q=red%20%2B%20blue%20%26%2050%25

既存URLを部品ごとに変更できる環境では、文字列連結よりURL APIやクエリパラメータ用APIを使う方が、どの部分をエンコードするか明確になります。App MuseumのURLエンコード・デコードツールへは、URLへ埋め込む値だけを入力するのが基本です。

特殊文字が問題になる理由

空白はパーセントエンコードでは通常 %20 になります。一方、application/x-www-form-urlencoded 形式では空白を + として表すため、元からあるプラス記号は %2B と区別する必要があります。

& はクエリ項目の区切り、= は名前と値の区切り、# はフラグメントの開始として解釈される場合があります。値にこれらを含めるなら、それぞれ %26%3D%23 とすることでデータとして保持できます。%% と2桁の16進数からなるエンコード表記を始めるため、文字として渡す場合は %25 になります。

raw value: plan=a&note=#1
encoded: plan%3Da%26note%3D%231

よくある失敗は、フォーム形式の + を常にプラス記号としてデコードすること、または値の中の & を未変換のまま連結して別パラメータにしてしまうことです。利用先が通常のURLコンポーネントとフォーム形式のどちらを期待するか確認してください。

二重エンコードを見分ける

すでにエンコード済みの %20 をもう一度エンコードすると、%%25 になり %2520 へ変わります。受信側で一度デコードしても %20 が残り、期待した空白へ戻らないのが典型的な兆候です。

original: a b
once: a%20b
twice: a%2520b
decode once from twice: a%20b

入力が生の文字列か、すでにエンコード済みかを処理境界で決め、同じ値へ複数の層でエンコードをかけないでください。% の後ろに16進数2桁が繰り返し現れるだけでは二重エンコードと断定できないため、元の値と往復結果を比較します。不完全な % や不正なUTF-8列はデコードエラーになることがあります。

encodeとdecodeを往復して確認する

  1. 実在データではなく、同じ種類の特殊文字を含むテスト値を用意します。
  2. URLエンコード・デコードツールで値をEncodeします。
  3. 出力を新しい入力としてDecodeします。
  4. デコード結果が最初の文字列と文字単位で一致するか確認します。
  5. 完成URLでは、値が一つのクエリ項目内に収まり、意図しないフラグメントや追加項目が生じていないか確認します。

東京 + café なら、エンコード後に非ASCII文字と空白と + が変換され、デコード後はアクセント記号を含む元の文字列へ戻ることを確認します。見た目が似るUnicode文字もあるため、必要ならコードポイントや文字列長も確認してください。

秘密情報を使わずにテストする

署名付きURL、パスワードリセットURL、OAuthの認証URL、APIキーやセッショントークンを含むURLは、コピー履歴、画面共有、ログなどから漏れる可能性があります。App Museumの処理はブラウザ内で完結しますが、テストには https://example.com/ と架空の値を使い、実在する秘密情報を貼り付けないでください。

参考資料

開発者向けurlpercent-encodingquery-parameterencodedecode