encodeURI()

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

试一试

语法

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://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() 与 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 语言规范
# sec-encodeuri-uri

浏览器兼容性

BCD 表仅在浏览器中加载

另请参阅