JavaScriptでURLを扱うときに、encodeURI と encodeURIComponent のどちらを使えばよいか迷うことがあります。
結論からいうと、ざっくり次のように考えると分かりやすいです。
- URL全体をエンコードしたい場合:
encodeURI - クエリパラメータの値をエンコードしたい場合:
encodeURIComponent
違いのイメージ
たとえば、次のようなURLがあります。
const url = "https://example.com/search?q=日本語 URL";
このURL全体に encodeURI を使うと、URLとして必要な :, /, ?, = などは残されます。
console.log(encodeURI(url));
結果は次のようになります。
https://example.com/search?q=%E6%97%A5%E6%9C%AC%E8%AA%9E%20URL
URL全体の形を壊したくない場合は、encodeURI が向いています。
クエリパラメータにはencodeURIComponentを使う
検索キーワードなど、URLの一部として入れる値には encodeURIComponent を使います。
const keyword = "日本語 URL";
const url = "https://example.com/search?q=" + encodeURIComponent(keyword);
console.log(url);
結果は次のようになります。
https://example.com/search?q=%E6%97%A5%E6%9C%AC%E8%AA%9E%20URL
このように、パラメータの値だけを安全にURLへ入れたい場合は encodeURIComponent を使うのが基本です。
& や = を含む値では特に注意
たとえば、検索キーワードに & や = が含まれている場合を考えます。
const keyword = "a=1&b=2";
これをそのままURLに入れると、URLの区切りとして解釈される可能性があります。
const badUrl = "https://example.com/search?q=" + keyword;
console.log(badUrl);
結果:
https://example.com/search?q=a=1&b=2
この場合、b=2 が別のパラメータのように見えてしまいます。
正しくは、値の部分に encodeURIComponent を使います。
const keyword = "a=1&b=2";
const goodUrl = "https://example.com/search?q=" + encodeURIComponent(keyword);
console.log(goodUrl);
結果:
https://example.com/search?q=a%3D1%26b%3D2
& や = がエンコードされるため、1つの値として安全に扱えます。
encodeURIとencodeURIComponentの違い
大きな違いは、URLの区切りとして使われる記号をエンコードするかどうかです。
| 文字 | encodeURI | encodeURIComponent |
|---|---|---|
: |
そのまま | %3A |
/ |
そのまま | %2F |
? |
そのまま | %3F |
& |
そのまま | %26 |
= |
そのまま | %3D |
| 日本語 | エンコード | エンコード |
| スペース | %20 |
%20 |
encodeURI はURL全体の形をなるべく残します。
一方、encodeURIComponent はURLの一部として入れる値を安全に扱うため、& や = などもエンコードします。
使い分けの目安
| 目的 | 使うもの |
|---|---|
| 完成済みのURL全体を扱う | encodeURI |
| 検索キーワードをURLに入れる | encodeURIComponent |
| クエリパラメータの値を作る | encodeURIComponent |
& や = を含む値を安全に扱う |
encodeURIComponent |
個人的には、クエリパラメータを手で組み立てる場面では、基本的に encodeURIComponent を使うことが多いです。
URLSearchParamsを使う方法
最近は、複数のクエリパラメータを扱うなら URLSearchParams を使う方が安全です。
const params = new URLSearchParams({
q: "日本語 URL",
type: "a=1&b=2"
});
const url = "https://example.com/search?" + params.toString();
console.log(url);
結果:
https://example.com/search?q=%E6%97%A5%E6%9C%AC%E8%AA%9E+URL&type=a%3D1%26b%3D2
自分で & や = を連結するより、ミスが起きにくくなります。
スペースが %20 ではなく + になる場合
encodeURIComponent では、スペースは %20 になります。
console.log(encodeURIComponent("日本語 URL"));
結果:
%E6%97%A5%E6%9C%AC%E8%AA%9E%20URL
一方、URLSearchParams を使うと、クエリ文字列ではスペースが + になることがあります。
const params = new URLSearchParams({
q: "日本語 URL"
});
console.log(params.toString());
結果:
q=%E6%97%A5%E6%9C%AC%E8%AA%9E+URL
これはフォーム送信などで使われる形式に近い表現です。どちらも場面によって使われます。
よくある間違い
URL全体にencodeURIComponentを使ってしまう
完成済みのURL全体に encodeURIComponent を使うと、https:// の : や / までエンコードされます。
const url = "https://example.com/search?q=日本語";
console.log(encodeURIComponent(url));
結果:
https%3A%2F%2Fexample.com%2Fsearch%3Fq%3D%E6%97%A5%E6%9C%AC%E8%AA%9E
この文字列は、URL全体としてそのまま開く用途には向いていません。
パラメータ値にencodeURIを使ってしまう
クエリパラメータの値に encodeURI を使うと、& や = が残ってしまう場合があります。
const keyword = "a=1&b=2";
const url = "https://example.com/search?q=" + encodeURI(keyword);
console.log(url);
結果:
https://example.com/search?q=a=1&b=2
この場合、b=2 が別のパラメータのように扱われる可能性があります。
パラメータの値には、基本的に encodeURIComponent を使う方が安全です。
動作確認用のツール
URLエンコード・デコードの結果をすぐ確認したい場合は、ブラウザ上で確認できるツールを使うと便利です。
日本語、記号、スペース、クエリパラメータの変換結果を確認できます。
まとめ
- URL全体には
encodeURI - パラメータの値には
encodeURIComponent -
&や=を含む値はencodeURIComponentで処理する - 複数パラメータを扱うなら
URLSearchParamsが便利 - スペースは場面によって
%20や+になることがある
URL全体を変換したいのか、URLの一部の値を変換したいのかを分けて考えると、使い分けやすくなります。