CreaTools LogoCreaTools
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%これ
encodeURIURL全体滅多に使わない

違いは「&」の扱い

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 APIOAuth 1.0a、厳密なエンコード必須
Google APIencodeURIComponent で通常OK
StripeWebhook URLは未エンコードで登録
SlackBot 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

関連記事