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());