encodeURI()

Baseline 已广泛支持

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

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

试一试

const uri = "https://mozilla.org/?x=шеллы";
const encoded = encodeURI(uri);
console.log(encoded);
// Expected output: "https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"

try {
  console.log(decodeURI(encoded));
  // Expected output: "https://mozilla.org/?x=шеллы"
} catch (e) {
  // Catches a malformed URI
  console.error(e);
}

语法

js
encodeURI(uri)

参数

uri

要编码为 URI 的字符串。

返回值

一个新字符串,表示作为 URI 编码的所提供字符串。

异常

URIError

如果 uri 包含孤立代理则抛出错误。

描述

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

encodeURI() 函数通过 UTF-8 代码单元转义字符,每个八位字节以 %XX 格式编码,必要时用 0 左填充。由于 UTF-16 中的孤立代理不编码任何有效的 Unicode 字符,它们会导致 encodeURI() 抛出 URIError

encodeURI() 转义所有字符除了

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

; / ? : @ & = + $ , #

第二行中的字符是可能属于 URI 语法的字符,并且仅由 encodeURIComponent() 进行转义。encodeURI()encodeURIComponent() 都不编码字符 -.!~*'(),这些字符被称为“非保留标记”,它们没有保留用途,但允许在 URI 中“原样”存在。(参见 RFC2396

encodeURI() 函数不编码对 URI 具有特殊含义(保留字符)的字符。以下示例显示了 URI 可能包含的所有部分。请注意某些字符如何用于表示特殊含义

url
http://username:password@www.example.com:80/path/to/file.php?foo=316&bar=this+has+spaces#anchor

encodeURI,顾名思义,用于将整个 URL 编码,假设它已经格式良好。如果你想将字符串值动态组装成一个 URL,你可能需要对每个动态段使用 encodeURIComponent(),以避免在不需要的地方出现 URL 语法字符。

js
const name = "Ben & Jerry's";

// This is bad:
const link = encodeURI(`https://example.com/?choice=${name}`); // "https://example.com/?choice=Ben%20&%20Jerry's"
console.log([...new URL(link).searchParams]); // [['choice', 'Ben '], [" Jerry's", '']

// Instead:
const link = encodeURI(
  `https://example.com/?choice=${encodeURIComponent(name)}`,
);
// "https://example.com/?choice=Ben%2520%2526%2520Jerry's"
console.log([...new URL(link).searchParams]); // [['choice', "Ben%20%26%20Jerry's"]]

示例

encodeURI() vs. encodeURIComponent()

encodeURI()encodeURIComponent() 的区别如下

js
const set1 = ";/?:@&=+$,#"; // Reserved Characters
const set2 = "-.!~*'()"; // Unreserved Marks
const set3 = "ABC abc 123"; // Alphanumeric Characters + Space

console.log(encodeURI(set1)); // ;/?:@&=+$,#
console.log(encodeURI(set2)); // -.!~*'()
console.log(encodeURI(set3)); // ABC%20abc%20123 (the space gets encoded as %20)

console.log(encodeURIComponent(set1)); // %3B%2C%2F%3F%3A%40%26%3D%2B%24%23
console.log(encodeURIComponent(set2)); // -.!~*'()
console.log(encodeURIComponent(set3)); // ABC%20abc%20123 (the space gets encoded as %20)

编码孤立代理会抛出错误

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

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

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

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

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

RFC3986 编码

最新的 RFC3986 将方括号保留(用于 IPv6),因此在形成可能作为 URL 一部分的内容(例如主机)时不会被编码。它还保留了 !、'、(、) 和 *,尽管这些字符没有正式的 URI 分隔用途。以下函数用于对符合 RFC3986 的 URL 格式的字符串进行编码。

js
function encodeRFC3986URI(str) {
  return encodeURI(str)
    .replace(/%5B/g, "[")
    .replace(/%5D/g, "]")
    .replace(
      /[!'()*]/g,
      (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`,
    );
}

规范

规范
ECMAScript® 2026 语言规范
# sec-encodeuri-uri

浏览器兼容性

另见