JavaScript7 分で読めます

encodeURI と encodeURIComponent の違いとは?

encodeURI は URL 全体をエンコードし、/、?、# などの構造上の文字はそのまま残します。encodeURIComponent は URI の 1 つのコンポーネントをエンコードし、/、?、& を含むすべての特殊文字をエンコードします。クエリパラメータの値には encodeURIComponent を、URL 全体には encodeURI を使いましょう。

encodeURI() とは?

encodeURI() は、完全な URI(Uniform Resource Identifier)をエンコードするために設計された JavaScript の組み込み関数です。URI 内で有効でない文字を、対応する percent-encoding 形式に変換しますが、URI 内で構造上の意味を持つ文字は意図的にそのまま残します。

具体的には、encodeURI() は次の文字をエンコードしませんA-Z a-z 0-9 ; , / ? : @ & = + $ - _ . ! ~ * ' ( ) #。つまり、エンコード後も URL 全体の構造は保たれます。

// encodeURI() は URL の構造を保持する
const url = 'https://example.com/my page?name=John Doe&city=New York';
console.log(encodeURI(url));
// "https://example.com/my%20page?name=John%20Doe&city=New%20York"
// 注目::、/、?、&、= はエンコードされない

この動作により、encodeURI() は、スペースや非 ASCII 文字を含む可能性はあるものの、構造上の文字(プロトコル区切り、パスの区切り、クエリ文字列のマーカー)はそのまま残したい完全な URL に最適です。

encodeURIComponent() とは?

encodeURIComponent() は、クエリパラメータの値やパスセグメントなど、URI の 1 つのコンポーネントをエンコードするために設計されています。encodeURI() とは異なり、URL 内で構造上の意味を持つ文字を含め、ほぼすべての特殊文字をエンコードします。

encodeURIComponent()エンコードしない文字は次のものだけです: A-Z a-z 0-9 - _ . ! ~ * ' ( )/?&=#: を含め、それ以外のすべては percent-encoding されます。

// encodeURIComponent() は非予約文字を除きすべてをエンコードする
const value = 'Tom & Jerry / Friends?';
console.log(encodeURIComponent(value));
// "Tom%20%26%20Jerry%20%2F%20Friends%3F"
// 注目:&、/、? はエンコードされる

// クエリパラメータを含む URL を組み立てる
const url = 'https://example.com/search?q=' + encodeURIComponent(value);
// "https://example.com/search?q=Tom%20%26%20Jerry%20%2F%20Friends%3F"

構造上の文字までエンコードしてしまうため、完全な URL に対して encodeURIComponent() を使ってはいけません。そうすると ://、すべての / パス区切り、そして ? クエリ区切りがエンコードされ、URL が使えなくなってしまいます。

主な違いの一覧

特徴 encodeURI() encodeURIComponent()
目的 URI 全体をエンコードする URI のコンポーネントをエンコードする
/ をエンコードするか いいえ はい(%2F
? をエンコードするか いいえ はい(%3F
& をエンコードするか いいえ はい(%26
= をエンコードするか いいえ はい(%3D
# をエンコードするか いいえ はい(%23
: をエンコードするか いいえ はい(%3A
スペースをエンコードするか はい(%20 はい(%20
Unicode をエンコードするか はい はい

それぞれをいつ使うべきか

ルールは単純です。URL 全体を、その構造を有効に保ったままエンコードしたいときは encodeURI() を使います。URL に挿入する 1 つの値をエンコードしたいときは encodeURIComponent() を使います。

// シナリオ 1:スペースを含む完全な URL をエンコードする
const fullUrl = 'https://example.com/my documents/file name.pdf';
const encoded = encodeURI(fullUrl);
// "https://example.com/my%20documents/file%20name.pdf"

// シナリオ 2:パーツから URL を組み立てる
const baseUrl = 'https://api.example.com/search';
const query = 'price >= 100 & category = books';
const finalUrl = baseUrl + '?q=' + encodeURIComponent(query);
// "https://api.example.com/search?q=price%20%3E%3D%20100%20%26%20category%20%3D%20books"

// シナリオ 3:リダイレクト URL をパラメータとしてエンコードする
const redirectUrl = 'https://example.com/callback?token=abc';
const loginUrl = 'https://auth.example.com/login?redirect=' +
  encodeURIComponent(redirectUrl);
// リダイレクト URL 全体が 1 つのパラメータ値としてエンコードされる

よくある間違いとその回避方法

間違い 1:クエリパラメータの値に encodeURI() を使う。 encodeURI()&= をエンコードしないため、これらの文字を含むパラメータ値に使うとクエリ文字列の構造が壊れてしまいます。

// 誤り
const bad = 'https://example.com/search?q=' + encodeURI('salt & pepper');
// "https://example.com/search?q=salt%20&%20pepper"
// サーバーは q="salt " と、余分なパラメータ " pepper" を受け取ってしまう

// 正しい
const good = 'https://example.com/search?q=' + encodeURIComponent('salt & pepper');
// "https://example.com/search?q=salt%20%26%20pepper"

間違い 2:URL 全体に encodeURIComponent() を使う。 これは、すべてのスラッシュ、コロン、クエスチョンマークをエンコードしてしまい、URL の構造を破壊します。

// 誤り
console.log(encodeURIComponent('https://example.com/path?key=value'));
// "https%3A%2F%2Fexample.com%2Fpath%3Fkey%3Dvalue"
// これはもう有効な URL ではない!

// 正しい
console.log(encodeURI('https://example.com/path?key=value'));
// "https://example.com/path?key=value"(すでに有効で、エンコードすべきものはない)

間違い 3:二重エンコード。 文字列がすでに percent-encoding されている場合、再度エンコードすると % 記号までエンコードされ、%20%2520 になってしまいます。エンコード関数を適用する前に、その値がすでにエンコード済みでないかを必ず確認しましょう。

より安全な最近の代替手段は URL および URLSearchParams API です。これらはエンコードを自動的に処理し、こうした落とし穴を完全に回避するのに役立ちます。

関連記事

無料ツールを試す