URL Encode
URLエンコード完全ガイド|encodeURI と encodeURIComponent の違いと正解
2025-12-09
覚えるのはこれだけ
99%のWeb実装では
encodeURIComponentだけ覚えればいい。迷ったら
encodeURIComponent。それで事故らない。
// ✓ これだけ覚えろ
const url = `https://api.example.com/search?q=${encodeURIComponent(value)}`;
以下は「なぜそう言えるか」と「残り1%の例外」の話。
即決フロー
┌─────────────────────────────────────────┐
│ 何をエンコードしたい? │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ クエリパラメータの値? │
│ 例: ?q=東京&大阪 の「東京&大阪」部分 │
└─────────────────────────────────────────┘
↓ Yes
┌─────────────────────────────────────────┐
│ ✓ encodeURIComponent │
│ (99%はこれ) │
└─────────────────────────────────────────┘
↓ No
┌─────────────────────────────────────────┐
│ URL全体(日本語パスを含む)? │
│ 例: https://example.com/東京/観光 │
└─────────────────────────────────────────┘
↓ Yes
┌─────────────────────────────────────────┐
│ encodeURI │
└─────────────────────────────────────────┘
↓ No
┌─────────────────────────────────────────┐
│ 迷った? → encodeURIComponent │
└─────────────────────────────────────────┘
この記事が解決する状況
| あなたの状況 | 読むべきセクション |
|---|---|
| encodeURI と encodeURIComponent の違いがわからない | 2つの関数の違い |
| APIに日本語を送ると文字化けする | クエリパラメータの正しい処理 |
| URLをパラメータとして渡したい | URLをパラメータで渡す |
| 「%25」が含まれるURLが返ってくる | 二重エンコード問題 |
| OAuth認証で署名エラーが出る | API連携での注意点 |
なぜURLエンコードが必要か
URLには「使える文字」が決まっている。日本語や一部の記号は使えない。
使えない: 東京 & 大阪 スペース
使える: A-Z a-z 0-9 - _ . ~
使えない文字を %E6%9D%B1 のような形式に変換するのがURLエンコード。
エンコードしないと起きる事故
| 状況 | 事故 |
|---|---|
?q=東京&大阪 をそのまま送信 | 「東京」と「大阪」が別パラメータになる |
| 日本語URLをメールに貼る | リンクが途中で切れる |
| SNSでシェア | リンクが開けない |
| APIにパラメータを渡す | 文字化け、認証エラー |
2つの関数の違い
結論
| 関数 | 用途 | 覚え方 |
|---|---|---|
| encodeURIComponent | パラメータの値 | 99%これ |
| encodeURI | URL全体 | 滅多に使わない |
違いは「&」の扱い
encodeURI("&") // → &(そのまま)
encodeURIComponent("&") // → %26
この違いが、URLを壊すか壊さないかを決める。
実例
const query = "東京&大阪";
// ❌ encodeURI: &がそのまま → 「大阪」が別パラメータになる
`https://api.example.com?q=${encodeURI(query)}`
// → https://api.example.com?q=%E6%9D%B1%E4%BA%AC&%E5%A4%A7%E9%98%AA
// サーバーは q=東京, 大阪="" と解釈
// ✓ encodeURIComponent: &も%26に → 1つの値として送れる
`https://api.example.com?q=${encodeURIComponent(query)}`
// → https://api.example.com?q=%E6%9D%B1%E4%BA%AC%26%E5%A4%A7%E9%98%AA
// サーバーは q=東京&大阪 と解釈
クエリパラメータの正しい処理
基本パターン
const keyword = "東京 タワー";
const url = `https://api.example.com/search?q=${encodeURIComponent(keyword)}`;
複数パラメータの組み立て
const params = {
q: "東京 タワー",
category: "観光&グルメ",
page: 1
};
const query = Object.entries(params)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join("&");
const url = `https://api.example.com/search?${query}`;
URLSearchParams を使う方法(推奨)
const params = new URLSearchParams();
params.append("q", "東京 タワー");
params.append("category", "観光&グルメ");
const url = `https://api.example.com/search?${params.toString()}`;
自動でエンコードしてくれる。
URLをパラメータで渡す
OAuth認証のコールバックURLや、Webhook登録で「URL自体をパラメータとして送る」場合。
よくある事故
// ❌ エンコードなし
https://auth.example.com/authorize?redirect_uri=https://myapp.com/callback?session=123
// サーバーは以下のように解釈する:
// - redirect_uri = https://myapp.com/callback
// - session = 123 ← 別パラメータとして認識
正しい処理
const redirectUri = "https://myapp.com/callback?session=123";
const authUrl = `https://auth.example.com/authorize?redirect_uri=${encodeURIComponent(redirectUri)}`;
// → redirect_uri=https%3A%2F%2Fmyapp.com%2Fcallback%3Fsession%3D123
API連携での注意点
OAuth 1.0a の署名(厳密なエンコードが必要)
JavaScriptの encodeURIComponent は ! ' ( ) * をエンコードしないので、追加処理が必要:
function rfc3986Encode(str) {
return encodeURIComponent(str)
.replace(/!/g, '%21')
.replace(/'/g, '%27')
.replace(/\(/g, '%28')
.replace(/\)/g, '%29')
.replace(/\*/g, '%2A');
}
主要APIの傾向
| API | 注意点 |
|---|---|
| Twitter API | OAuth 1.0a、厳密なエンコード必須 |
| Google API | encodeURIComponent で通常OK |
| Stripe | Webhook URLは未エンコードで登録 |
| Slack | Bot tokenはエンコード不要 |
デコード(元に戻す)
const encoded = "%E6%9D%B1%E4%BA%AC";
const decoded = decodeURIComponent(encoded);
// → 東京
文字化けする場合
古いシステムでは Shift_JIS でエンコードされていることがある。UTF-8前提でデコードすると文字化けする。
二重エンコード問題
「%25」を見たら二重エンコード。
詳細は URLの二重エンコードで起きる事故と防ぎ方 を参照。
簡潔に言うと
%E6%9D%B1 を再度エンコードすると %25E6%259D%25B1 になる。
防ぎ方
- エンコードは処理の最後に1回だけ
- 入力元がエンコード済みかどうか確認する
よくある事故パターン
| 事故 | 原因 | 対処 |
|---|---|---|
& 以降が別パラメータになる | encodeURI を値に使った | encodeURIComponent に変更 |
URLが https%3A%2F%2F で始まる | URL全体に encodeURIComponent を使った | encodeURI に変更 |
%25 が含まれる | 二重エンコード | エンコードは1回だけ |
| OAuth署名エラー | 特殊文字のエンコード漏れ | RFC 3986準拠 |
まとめ
99%は encodeURIComponent。迷ったら encodeURIComponent。
| やりたいこと | 使う関数 |
|---|---|
| クエリパラメータの値 | encodeURIComponent |
| URLをパラメータとして渡す | encodeURIComponent |
| URL全体(日本語パス含む) | encodeURI |
| OAuth署名 | RFC 3986準拠 |
| 迷った | encodeURIComponent |
関連記事
- URLの二重エンコードで起きる事故と防ぎ方 — 「%25」問題の詳細