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エンコード済み文字列を相互変換できます。コピー・入出力の入れ替えボタン付きで効率よく変換作業ができます。