encodeURIComponent()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
encodeURIComponent()
関数は URI を、特定の文字の各インスタンスを、その文字の UTF-8 エンコード方式を表す 1 つから 4 つのエスケープシーケンスで置き換えることでエンコードします (2 つのサロゲート文字で構成される文字の場合は 4 つのエスケープシーケンスになります)。 encodeURI()
と比較すると、この関数は URI 構文の一部を含むより多くの文字をエンコードします。
試してみましょう
構文
encodeURIComponent(uriComponent)
引数
uriComponent
-
URI の部分(パス、クエリー文字列、フラグメントなど)としてエンコードされる文字列。他にも文字列に変換される値があります。
返値
与えられた文字列を表す URI 構成要素としてエンコードされた新しい文字列です。
例外
返値
encodeURIComponent()
はグローバルオブジェクトの関数プロパティです。
encodeURIComponent
は encodeURI()
で説明されているのと同じエンコーディングアルゴリズムを使用します。下記を除くすべての文字をエスケープします。
A–Z a–z 0–9 - _ . ! ~ * ' ( )
encodeURI()
と比較すると、 encodeURIComponent()
はより多くの文字セットをエスケープします。 encodeURIComponent()
は、サーバーに POST
されたフォームからユーザーが入力した項目に対して使用します。これは、文字参照やその他エンコード/デコードを要求される文字について、 データ入力中に不用意に発生する可能性のある記号をエンコードします。例えば、ユーザーが Jack & Jill
と入力した場合、テキストは Jack & Jill
とエンコードされる可能性があります。encodeURIComponent()
を使用しない場合は "&" が新しいフィールドの始まりとしてサーバー上で解釈され、データの完全性が損なわれる可能性があります。
application/x-www-form-urlencoded
では、スペースは +
に置換されます。そのため、encodeURIComponent()
による置換に加えて %20
を +
に置き換えることが望まれるかもしれません。
例
Content-Disposition とリンクヘッダーのエンコーディング
次の例は、サーバーレスポンスヘッダー引数の Content-Disposition
や Link
で (UTF-8 からなるファイル名などに) 必要となる特別な UTF-8 エンコーディングを提供します。
const fileName = "my file(2).txt";
const header = `Content-Disposition: attachment; filename*=UTF-8''${encodeRFC5987ValueChars(
fileName,
)}`;
console.log(header);
// "Content-Disposition: attachment; filename*=UTF-8''my%20file%282%29.txt"
function encodeRFC5987ValueChars(str) {
return (
encodeURIComponent(str)
// The following creates the sequences %27 %28 %29 %2A (Note that
// the valid encoding of "*" is %2A, which necessitates calling
// toUpperCase() to properly encode). Although RFC3986 reserves "!",
// RFC5987 does not, so we do not need to escape it.
.replace(
/['()*]/g,
(c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`,
)
// The following are not required for percent-encoding per RFC5987,
// so we can allow for a little better readability over the wire: |`^
.replace(/%(7C|60|5E)/g, (str, hex) =>
String.fromCharCode(parseInt(hex, 16)),
)
);
}
RFC3986 のエンコーディング
最新の RFC3986 では、 !
, '
, (
, )
, *
を、たとえこれらの文字が正式な URI 区切り文字として使用されていないとしても予約しています。 IPv6 の URI 構文の一部である [
と ]
もエンコードします。 RFC3986 に準拠した encodeURI
の実装では、これらをエスケープすべきではありません。これは encodeURI() の例で示されています。
function encodeRFC3986URIComponent(str) {
return encodeURIComponent(str).replace(
/[!'()*]/g,
(c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`,
);
}
孤立サロゲートのエンコードによる例外
上位・下位のペアでないサロゲート文字をエンコードしようとした場合 URIError
が発生します。
// 上位・下位の正しいペア
encodeURIComponent("\uD800\uDFFF"); // "%F0%90%8F%BF"
// 上位のみであり "URIError: malformed URI sequence" が発生
encodeURIComponent("\uD800");
// 下位のみであり "URIError: malformed URI sequence" が発生
encodeURIComponent("\uDFFF");
String.prototype.toWellFormed()
を使用することができます。これは孤立サロゲートを Unicode 置換文字 (U+FFFD) に置き換えることで、このエラーを避けることができます。また、 String.prototype.isWellFormed()
を使用することで、文字列を encodeURIComponent()
に渡す前に、孤立サロゲートが含まれているかどうかを調べることができます。
仕様書
Specification |
---|
ECMAScript Language Specification # sec-encodeuricomponent-uricomponent |
ブラウザーの互換性
BCD tables only load in the browser