URLエンコードとは? — パーセントエンコーディングの仕組みと使い方

URLエンコード(パーセントエンコーディング)とは、URLの中で使えない特殊文字や日本語などのマルチバイト文字を「%XX」形式の16進数表記に変換する方式です。URLで使用できる文字はRFC 3986によって厳密に定められており、それ以外の文字はこの変換を経て安全に送受信されます。

最終更新: 2026年5月22日

目次
  1. URLエンコードとは
  2. エンコードの仕組み
  3. エンコードが必要な文字一覧
  4. encodeURI vs encodeURIComponent
  5. ツールの使い方
  6. 開発での活用場面
  7. よくある質問

URLエンコードとは

定義: URLエンコード(パーセントエンコーディング)とは、URLの中で使用できない文字を 「%」+ 16進数2桁(%XX) の形式に変換するエスケープ方式です。RFC 3986 によって標準化されています。

URLで使えるのは英数字(A〜Z・a〜z・0〜9)と一部の記号(-_.~)のみです。日本語や空白、&=? などの特殊文字はURLの構造的な意味を持つか、HTTP通信で安全に扱えないため、そのまま使うことはできません。

URLエンコードはこの問題を解決します。たとえば「東京」という2文字は、UTF-8でエンコードされた後に1バイトずつ「%」付きの16進数に変換され、URLの中で安全に扱える文字列になります。

エンコードの仕組み

原理: 文字を UTF-8のバイト列に変換し、各バイトを %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で非予約文字と定義されていない文字のみです。

エンコードが必要な文字一覧

ポイント: RFC 3986では文字を「非予約文字(エンコード不要)」「予約文字(構造的に特別な意味を持つ)」「その他(エンコード必須)」の3種類に分類しています。
文字 エンコード後 カテゴリ
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

使い分けの原則: URL全体を扱うなら 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'

ツールの使い方

Links Create の URLエンコードツール はインストール不要のブラウザ完結型です。日本語を含む任意のテキストを即座にエンコード・デコードできます。

3ステップで変換できます。

  1. モードを選択 — ページ上部の「エンコード」または「デコード」を選びます。
  2. テキストを入力 — 入力欄にエンコードしたいテキスト(日本語可)または %E6%9D%B1... 形式のエンコード済み文字列を貼り付けます。入力と同時に自動変換されます。
  3. 結果をコピー — 変換結果が自動表示されます。コピーボタンでクリップボードに保存できます。
  4. 二重エンコードを避ける — 既にエンコード済の文字列を再度エンコードすると %25 が混入して元に戻せなくなります。デコード結果を確認してから次のエンコードに進むのが安全です。
  5. 実シナリオで応用する — クエリパラメータ・OAuth redirect_uri・API リクエスト URL の生成等で実際にエンコード結果を埋め込んで動作確認します。

開発での活用場面

重要: URLエンコードが必要かどうかを判断するには「その文字列が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`;

よくある質問

空白は「+」と「%20」のどちらでエンコードすべきですか?

URLのパス部分では %20 を使います。クエリ文字列(? 以降)ではHTMLフォームの application/x-www-form-urlencoded 形式として + も使われますが、RFC 3986 準拠のパーセントエンコーディングでは %20 が正式です。API連携では %20 を使うのが安全です。

ブラウザは日本語URLを自動でエンコードしてくれますか?

はい、モダンブラウザはアドレスバーに入力された日本語を自動でUTF-8のパーセントエンコードに変換してサーバーへ送信します。ただし、JavaScriptやサーバーサイドコードで動的にURLを生成する場合は手動でエンコード処理が必要です。

URLエンコードとBase64エンコードの違いは何ですか?

URLエンコード(パーセントエンコーディング)はURLの特殊文字を %XX 形式に変換するもので、URL中で安全に文字を表現するために使います。Base64はバイナリデータを64種類のASCII文字に変換する方式で、主にメール添付・JWT・Data URIに使われます。目的・対象データ・用途がまったく異なります。詳しくは Base64解説ガイド もご覧ください。

ダブルエンコード(二重エンコード)とは何ですか?どう防ぎますか?

すでにエンコード済みの文字列をもう一度エンコードしてしまう問題です。例えば %20 を再エンコードすると %2520 になり、デコード後も %20 という文字列が残って正しく動作しません。デコードしてから再エンコードするか、エンコード済みかを事前に確認することで防げます。