encodeURIComponent と encodeURI の違い:どちらをいつ使うべきか
JavaScript の encodeURIComponent() 関数と encodeURI() 関数を、具体例とベストプラクティスを交えて詳しく比較します。
JavaScript の 2 つの URL エンコード関数
JavaScript には URL エンコード用の組み込み関数が 2 つあります。encodeURI() と encodeURIComponent() です。一見すると似ていますが、間違った方を使うと URL が壊れたり、セキュリティ上の脆弱性やデータの破損につながったりします。両者の違いを理解することは、Web 開発者にとって非常に重要です。
encodeURI() — 完全な URI 向け
encodeURI() は、完全な URI をエンコードするために設計された関数です。URI の構造上で特別な意味を持つ文字を除き、すべての文字をエンコードします。具体的には、次の文字はエンコードされません。
- 予約文字:
; , / ? : @ & = + $ # - 非予約文字:英字、数字、
- _ . ! ~ * ' ( )
// encodeURI は URI の構造を保持する
encodeURI('https://example.com/path?q=hello world&lang=en')
// "https://example.com/path?q=hello%20world&lang=en"
// 注意: :, /, ?, =, & はエンコードされない
encodeURIComponent() — URI のコンポーネント向け
encodeURIComponent() は、URI の単一のコンポーネント(クエリパラメータの値など)をエンコードするために設計された関数です。次の文字を除き、すべての文字をエンコードします。
- 非予約文字:英字、数字、
- _ . ! ~ * ' ( )
// encodeURIComponent は非予約文字を除くすべてをエンコードする
encodeURIComponent('hello world & goodbye')
// "hello%20world%20%26%20goodbye"
// 注意: & は予約文字なのでエンコードされる
// クエリパラメータの値として使う場合
const url = 'https://example.com/search?q=' +
encodeURIComponent('cats & dogs');
// "https://example.com/search?q=cats%20%26%20dogs"
よくある間違い
間違い 1:クエリの値に encodeURI を使う
アンパサンドを含むクエリパラメータの値を encodeURI() でエンコードすると、アンパサンドはエンコードされず、パラメータの区切り文字として解釈されてしまい、URL が壊れてしまいます。
// 誤り: 値に含まれるアンパサンドが URL を壊す
const badUrl = 'https://api.example.com/search?q=' +
encodeURI('Tom & Jerry');
// "https://api.example.com/search?q=Tom%20&%20Jerry"
// サーバーは q="Tom " と、値のないパラメータ " Jerry" として認識してしまう
// 正しい: encodeURIComponent を使う
const goodUrl = 'https://api.example.com/search?q=' +
encodeURIComponent('Tom & Jerry');
// "https://api.example.com/search?q=Tom%20%26%20Jerry"
// サーバーは正しく q="Tom & Jerry" として認識する
間違い 2:URL 全体に encodeURIComponent を使う
URL 全体に対して encodeURIComponent() を使うと、コロン、スラッシュ、クエスチョンマークなどの構造上の文字までエンコードされてしまい、URL がまったく使えなくなります。
どちらをいつ使うか:シンプルなルール
- 完全な URI があり、スペースや非 ASCII 文字を含む可能性はあるものの構造自体は正しい場合は、
encodeURI()を使う - URI に埋め込む単一のデータ(クエリパラメータの値、パスセグメントなど)をエンコードする場合は、
encodeURIComponent()を使う
URLSearchParams という選択肢
最近の JavaScript には、エンコードを自動的に処理してくれる URLSearchParams API があります。クエリ文字列を組み立てる際には、これが最良の方法であることが多いです。
const params = new URLSearchParams({
q: 'Tom & Jerry',
category: 'cartoons & animation',
page: '1'
});
const url = 'https://example.com/search?' + params.toString();
// "https://example.com/search?q=Tom+%26+Jerry&category=cartoons+%26+animation&page=1"
// または URL API を使う
const url2 = new URL('https://example.com/search');
url2.searchParams.set('q', 'Tom & Jerry');
console.log(url2.toString());