encodeURIComponent()

Baseline 已广泛支持

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

encodeURIComponent() 函数通过将某些字符的每个实例替换为一个、两个、三个或四个表示该字符 UTF-8 编码的转义序列来编码 URI(对于由两个代理字符组成的字符,只会是四个转义序列)。与 encodeURI() 相比,此函数编码的字符更多,包括那些作为 URI 语法一部分的字符。

试一试

// Encodes characters such as ?,=,/,&,:
console.log(`?x=${encodeURIComponent("test?")}`);
// Expected output: "?x=test%3F"

console.log(`?x=${encodeURIComponent("шеллы")}`);
// Expected output: "?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"

语法

js
encodeURIComponent(uriComponent)

参数

uriComponent

一个字符串,要编码为 URI 组件(路径、查询字符串、片段等)。其他值会转换为字符串

返回值

一个新字符串,表示提供的 uriComponent 编码为 URI 组件。

异常

URIError

如果 uriComponent 包含孤立代理,则抛出。

描述

encodeURIComponent() 是全局对象的函数属性。

encodeURIComponent() 使用与 encodeURI() 中描述的相同的编码算法。它会转义以下字符之外的所有字符

A–Z a–z 0–9 - _ . ! ~ * ' ( )

encodeURI() 相比,encodeURIComponent() 转义的字符集更大。将 encodeURIComponent() 用于发送到服务器的表单中的用户输入字段——这将编码在数据输入过程中可能无意生成的 & 符号,用于字符引用或其他需要编码/解码的字符。例如,如果用户输入 Jack & Jill,没有 encodeURIComponent(),服务器可能会将 & 解释为新字段的开始,从而危及数据完整性。

对于 application/x-www-form-urlencoded,空格应替换为 +,因此可能需要在 encodeURIComponent() 替换后,再将 %20 替换为 +

示例

以下示例提供了 UTF-8 Content-DispositionLink 服务器响应头参数(例如 UTF-8 文件名)所需的特殊编码

js
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 分隔用途。以下函数将字符串编码为符合 RFC3986 的 URL 组件格式。它还编码了 [],它们是 IPv6 URI 语法的一部分。符合 RFC3986 的 encodeURI 实现不应转义它们,这在 encodeURI() 示例中有所演示。

js
function encodeRFC3986URIComponent(str) {
  return encodeURIComponent(str).replace(
    /[!'()*]/g,
    (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`,
  );
}

编码孤立代理会抛出错误

如果尝试编码不属于高低代理对的代理,将抛出 URIError。例如

js
// High-low pair OK
encodeURIComponent("\uD800\uDFFF"); // "%F0%90%8F%BF"

// Lone high-surrogate code unit throws "URIError: malformed URI sequence"
encodeURIComponent("\uD800");

// Lone high-surrogate code unit throws "URIError: malformed URI sequence"
encodeURIComponent("\uDFFF");

你可以使用 String.prototype.toWellFormed(),它将孤立代理替换为 Unicode 替换字符 (U+FFFD),以避免此错误。你还可以使用 String.prototype.isWellFormed() 在将字符串传递给 encodeURIComponent() 之前检查它是否包含孤立代理。

规范

规范
ECMAScript® 2026 语言规范
# sec-encodeuricomponent-uricomponent

浏览器兼容性

另见