URLエンコードとは
URLで使えるのは英数字(A〜Z・a〜z・0〜9)と一部の記号(-・_・.・~)のみです。日本語や空白、&・=・? などの特殊文字はURLの構造的な意味を持つか、HTTP通信で安全に扱えないため、そのまま使うことはできません。
URLエンコードはこの問題を解決します。たとえば「東京」という2文字は、UTF-8でエンコードされた後に1バイトずつ「%」付きの16進数に変換され、URLの中で安全に扱える文字列になります。
エンコードの仕組み
%XX(XX は16進数2桁)に置き換えます。日本語1文字は通常3バイトになるため、%XX%XX%XX の9文字になります。
具体例:「東京」をURLエンコードする
「東京」をURLエンコードすると %E6%9D%B1%E4%BA%AC になります。変換の流れを追ってみましょう。
| ステップ | 内容 | 「東」の値 | 「京」の値 |
|---|---|---|---|
| 1. UTF-8バイト列に変換 | 文字をUTF-8の16進数バイト列で表す | E6 9D B1 |
E4 BA AC |
| 2. 各バイトに「%」を付加 | バイトごとに「%」プレフィックスを追加 | %E6%9D%B1 |
%E4%BA%AC |
| 3. 結合 | 各文字のエンコード結果を連結 | %E6%9D%B1%E4%BA%AC |
|
半角英数字はエンコードされません。たとえば Tokyo2026 はそのまま Tokyo2026 です。変換が必要なのは RFC 3986で非予約文字と定義されていない文字のみです。
エンコードが必要な文字一覧
| 文字 | エンコード後 | カテゴリ |
|---|---|---|
A〜Z、a〜z、0〜9 |
変換なし(そのまま) | 非予約文字 — 常に安全 |
- _ . ~ |
変換なし(そのまま) | 非予約文字 — 常に安全 |
| 空白(スペース) | %20(または +) |
要エンコード — フォームでは + も使用される |
& |
%26 |
予約文字 — クエリパラメータの区切り |
= |
%3D |
予約文字 — キーと値の区切り |
? |
%3F |
予約文字 — クエリ開始記号 |
# |
%23 |
予約文字 — フラグメント識別子 |
/ |
%2F |
予約文字 — パス区切り |
+ |
%2B |
予約文字 — フォームの空白表記と混同注意 |
: |
%3A |
予約文字 — スキームやポート区切り |
| 日本語(例:東) | %E6%9D%B1 |
非ASCII文字 — UTF-8バイトをエンコード |
| 絵文字(例:😀) | %F0%9F%98%80 |
非ASCII文字 — 4バイトUTF-8でエンコード |
空白の「+」と「%20」の違い
空白のエンコードには2つの表記があります。
%20: RFC 3986 のパーセントエンコーディング。URLのパス部分やREST APIで使う正式な形式。+: HTML フォームのapplication/x-www-form-urlencoded形式。?q=hello+worldのようにクエリ文字列内で使われる慣習。
どちらが正しいかは文脈によります。URLパス内では必ず %20 を使用し、フォームのクエリ文字列では + も許容されますが、混在すると誤動作の原因になるため統一することを推奨します。
encodeURI vs encodeURIComponent
encodeURI、クエリパラメータやパスの一部を扱うなら encodeURIComponent を使います。多くの場面では encodeURIComponent が安全な選択肢です。
| 関数 | エンコードしない文字 | 用途 |
|---|---|---|
encodeURI() |
英数字・-_.~・予約文字(; , / ? : @ & = + $ #) |
URL全体をエンコードしたいとき |
encodeURIComponent() |
英数字・-_.~ のみ |
クエリパラメータの値・パスの一部など |
(旧)escape() |
英数字・@*_+-./ |
非推奨 — 使用禁止 |
JavaScript コード例
encodeURI — URL全体のエンコード
const url = 'https://example.com/search?q=東京 旅行&lang=ja';
// encodeURI は予約文字(: / ? = & # 等)をエンコードしない
encodeURI(url);
// => 'https://example.com/search?q=%E6%9D%B1%E4%BA%AC%20%E6%97%85%E8%A1%8C&lang=ja'
encodeURIComponent — クエリパラメータの値をエンコード
const keyword = '東京 旅行&グルメ';
const encoded = encodeURIComponent(keyword);
// => '%E6%9D%B1%E4%BA%AC%20%E6%97%85%E8%A1%8C%26%E3%82%B0%E3%83%AB%E3%83%A1'
const apiUrl = `https://api.example.com/search?q=${encoded}`;
// => 'https://api.example.com/search?q=%E6%9D%B1%E4%BA%AC%20%E6%97%85%E8%A1%8C%26...'
デコード(復元)
// エンコードと対応するデコード関数
decodeURI('%E6%9D%B1%E4%BA%AC'); // => '東京'
decodeURIComponent('%E6%9D%B1%E4%BA%AC'); // => '東京'
Python コード例
from urllib.parse import quote, unquote, urlencode
# 文字列をパーセントエンコード(safe=''で英数字以外をすべてエンコード)
encoded = quote('東京 旅行&グルメ', safe='')
# => '%E6%9D%B1%E4%BA%AC%20%E6%97%85%E8%A1%8C%26%E3%82%B0%E3%83%AB%E3%83%A1'
# デコード
decoded = unquote(encoded)
# => '東京 旅行&グルメ'
# クエリパラメータを辞書から生成(推奨)
params = {'q': '東京 旅行', 'lang': 'ja', 'page': 1}
query_string = urlencode(params)
# => 'q=%E6%9D%B1%E4%BA%AC+%E6%97%85%E8%A1%8C&lang=ja&page=1'
ツールの使い方
3ステップで変換できます。
- モードを選択 — ページ上部の「エンコード」または「デコード」を選びます。
- テキストを入力 — 入力欄にエンコードしたいテキスト(日本語可)または
%E6%9D%B1...形式のエンコード済み文字列を貼り付けます。入力と同時に自動変換されます。 - 結果をコピー — 変換結果が自動表示されます。コピーボタンでクリップボードに保存できます。
- 二重エンコードを避ける — 既にエンコード済の文字列を再度エンコードすると
%25が混入して元に戻せなくなります。デコード結果を確認してから次のエンコードに進むのが安全です。 - 実シナリオで応用する — クエリパラメータ・OAuth
redirect_uri・API リクエスト URL の生成等で実際にエンコード結果を埋め込んで動作確認します。
開発での活用場面
クエリパラメータへの値の埋め込み
検索キーワードやユーザー入力をURLのクエリパラメータに含める場面は最も頻繁なケースです。& や = を含む値をそのまま埋め込むとURL構造が破壊されるため、encodeURIComponent が必須です。
// 悪い例(&が区切り文字として解釈される)
const bad = `/search?q=A&B&lang=ja`;
// 良い例
const good = `/search?q=${encodeURIComponent('A&B')}&lang=ja`;
// => '/search?q=A%26B&lang=ja'
フォーム送信(application/x-www-form-urlencoded)
HTMLフォームのデフォルト送信形式では、フォームの値が自動でURLエンコードされます。fetch で同じ形式を扱う場合は URLSearchParams を使うと安全です。
const params = new URLSearchParams({ name: '山田 太郎', city: '東京' });
await fetch('/api/register', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: params.toString(),
});
// body => 'name=%E5%B1%B1%E7%94%B0+%E5%A4%AA%E9%83%8E&city=%E6%9D%B1%E4%BA%AC'
リダイレクト先URLの埋め込み
ログイン後のリダイレクト先URLをクエリパラメータに含める場面では、URL全体をエンコードする必要があります。/ や ? まで含めてエンコードしなければ意図しない挙動になります。
const returnUrl = 'https://example.com/dashboard?tab=settings';
const loginUrl = `/login?redirect=${encodeURIComponent(returnUrl)}`;
// => '/login?redirect=https%3A%2F%2Fexample.com%2Fdashboard%3Ftab%3Dsettings'
外部API呼び出し
地図APIや検索APIに日本語の地名やキーワードを渡す場合は、各パラメータの値を encodeURIComponent してから連結します。多くのHTTPクライアントライブラリは自動でエンコードしてくれますが、動作を明示的にコントロールしたい場面では手動処理が確実です。
const place = encodeURIComponent('浅草寺');
const apiUrl = `https://maps.googleapis.com/maps/api/geocode/json?address=${place}&key=YOUR_KEY`;