JavaScript8 分钟阅读

encodeURIComponent 与 encodeURI:该在何时使用哪一个

深入对比 JavaScript 的 encodeURIComponent() 和 encodeURI() 函数,附带示例与最佳实践。

JavaScript 的两个 URL 编码函数

JavaScript 提供了两个内置的 URL 编码函数:encodeURI()encodeURIComponent()。它们看起来很相似,但用错了就可能导致 URL 损坏、安全漏洞或数据损坏。对于 Web 开发者来说,理解二者的区别至关重要。

encodeURI() —— 用于完整的 URI

encodeURI() 用于对完整的 URI 进行编码。它会编码所有字符,但会保留那些在 URI 结构中具有特殊含义的字符。具体来说,它不会编码:

  • 保留字符:; , / ? : @ & = + $ #
  • 非保留字符:字母、数字,以及 - _ . ! ~ * ' ( )
// encodeURI 会保留 URI 的结构
encodeURI('https://example.com/path?q=hello world&lang=en')
// "https://example.com/path?q=hello%20world&lang=en"
// 注意::、/、?、=、& 不会被编码

encodeURIComponent() —— 用于 URI 的组成部分

encodeURIComponent() 用于对 URI 的单个组成部分(例如查询参数的值)进行编码。它会编码除以下字符之外的所有字符:

  • 非保留字符:字母、数字,以及 - _ . ! ~ * ' ( )
// encodeURIComponent 会编码除非保留字符之外的所有字符
encodeURIComponent('hello world & goodbye')
// "hello%20world%20%26%20goodbye"
// 注意:& 会被编码,因为它是保留字符

// 将其用于查询参数的值
const url = 'https://example.com/search?q=' +
  encodeURIComponent('cats & dogs');
// "https://example.com/search?q=cats%20%26%20dogs"

常见错误

错误 1:用 encodeURI 编码查询参数的值

如果你用 encodeURI() 去编码一个包含 & 符号的查询参数值,这个 & 符号不会被编码,从而会被当作参数分隔符来解析,破坏你的 URL。

// 错误:值中的 & 符号破坏了 URL
const badUrl = 'https://api.example.com/search?q=' +
  encodeURI('Tom & Jerry');
// "https://api.example.com/search?q=Tom%20&%20Jerry"
// 服务器看到的是:q="Tom ",以及一个没有值的参数 " Jerry"

// 正确:使用 encodeURIComponent
const goodUrl = 'https://api.example.com/search?q=' +
  encodeURIComponent('Tom & Jerry');
// "https://api.example.com/search?q=Tom%20%26%20Jerry"
// 服务器正确地看到:q="Tom & Jerry"

错误 2:用 encodeURIComponent 编码完整的 URL

如果你对整个 URL 使用 encodeURIComponent(),它会把冒号、斜杠、问号以及其他结构性字符都编码掉,使这个 URL 完全无法使用。

该用哪一个:简单的判断规则

  • 当你有一个完整的 URI,它可能包含空格或非 ASCII 字符,但结构本身是有效的时候,使用 encodeURI()
  • 当你要编码将要放入 URI 中的单个数据片段(查询参数的值、路径片段等)时,使用 encodeURIComponent()

URLSearchParams:另一种选择

现代 JavaScript 提供了 URLSearchParams API,它会自动处理编码。在构建查询字符串时,这通常是最佳方案:

const params = new URLSearchParams({
  q: 'Tom & Jerry',
  category: 'cartoons & animation',
  page: '1'
});

const url = 'https://example.com/search?' + params.toString();
// "https://example.com/search?q=Tom+%26+Jerry&category=cartoons+%26+animation&page=1"

// 或者使用 URL API
const url2 = new URL('https://example.com/search');
url2.searchParams.set('q', 'Tom & Jerry');
console.log(url2.toString());

相关文章

试用我们的免费工具