URLには使用できる文字に制限があります。日本語・スペース・記号などを含む場合はURLエンコード(パーセントエンコーディング)と呼ばれる変換が必要です。Webサービス開発やAPIの利用時に必須の知識です。
URLエンコードとは
URLで使える文字は英数字と一部の記号(- _ . ~)のみです。それ以外の文字は % と16進数2桁に変換されます。
スペース → %20
日本語「東京」→ %E6%9D%B1%E4%BA%AC
? → %3F
& → %26
= → %3D
+ → %2B
# → %23
## 変換の仕組み
文字をUTF-8バイト列に変換し、各バイトを %XX 形式で表記します。
「東」のUTF-8: E6 9D B1
エンコード後: %E6%9D%B1
## JavaScriptでのエンコード・デコード
JavaScriptには用途の異なる3つの関数があります。
encodeURIComponent — パラメータの値に使う
URLのクエリパラメータの値をエンコードする際に使います。& や = もエンコードするため、値として安全に扱えます。
const keyword = '東京 渋谷';
const url = `https://example.com/search?q=${encodeURIComponent(keyword)}`;
// → https://example.com/search?q=%E6%9D%B1%E4%BA%AC%20%E6%B8%8B%E8%B0%B7
### encodeURI — URL全体に使う
& = ? # などURLの構造を示す記号はエンコードしません。URL全体を安全な形に変換する際に使います。
const url = encodeURI('https://example.com/search?q=東京');
// → https://example.com/search?q=%E6%9D%B1%E4%BA%AC
### decodeURIComponent — デコードに使う
エンコードされた文字列を元に戻します。
decodeURIComponent('%E6%9D%B1%E4%BA%AC');
// → 東京
### 使い分けの基準
| 用途 | 使う関数 |
|---|---|
| クエリパラメータの値 | encodeURIComponent |
| URL全体を扱う | encodeURI |
| エンコードを戻す | decodeURIComponent |
PHPでのエンコード・デコード
// エンコード
urlencode('東京 渋谷');
// → %E6%9D%B1%E4%BA%AC+%E6%B8%8B%E8%B0%B7(スペースは+になる)
rawurlencode('東京 渋谷');
// → %E6%9D%B1%E4%BA%AC%20%E6%B8%8B%E8%B0%B7(スペースは%20になる)
// デコード
urldecode('%E6%9D%B1%E4%BA%AC');
// → 東京
urlencode はスペースを + に変換します。APIのクエリパラメータには rawurlencode(スペースを %20 に)を使うのが安全です。
よくある文字化けの原因
フォームの文字コードが合っていない
HTMLフォームが UTF-8 で、サーバー側が EUC-JP で処理している場合に文字化けが発生します。現在はすべて UTF-8 に統一するのが標準です。
<meta charset="UTF-8">
<form accept-charset="UTF-8">
### + と %20 の混在
+ はフォームデータのスペース表現で、URLのパス部分では使えません。パスにスペースを含む場合は %20 を使います。
二重エンコード
エンコード済みの文字列をさらにエンコードすると %25 (% のエンコード)が含まれ、デコードしても元に戻らなくなります。
// ❌ 二重エンコード
encodeURIComponent(encodeURIComponent('東京'));
// → %25E6%259D%25B1%25E4%25BA%25AC
// ✅ 一回だけエンコード
encodeURIComponent('東京');
// → %E6%9D%B1%E4%BA%AC
URLエンコード・デコードツールでは、テキストとURLエンコード済み文字列を相互変換できます。コピー・入出力の入れ替えボタン付きで効率よく変換作業ができます。