彻底搞懂 URL 编码 (Percent-encoding) 的原理与坑
在前端开发中,我们经常会在浏览器地址栏看到类似 %E6%B5%8B%E8%AF%95 这样的乱码。这其实就是 URL 编码(URL Encoding),也叫百分号编码。
今天我们来深挖一下它的底层逻辑。
为什么需要 URL 编码?
根据 RFC 3986 标准,URL 只能使用 ASCII 字符集中的一小部分字符。 具体来说,只有以下字符是安全的:
- 英文字母(a-z, A-Z)
- 数字(0-9)
- 少数几个特殊字符:
- _ . ~
如果 URL 中出现了除此之外的字符(比如汉字、空格),或者出现了 URL 的“保留字符”(比如 ? & = / #),就必须对它们进行编码。
如果不编码会发生什么?
假设你有一个搜索接口 /search?q=a&b,你的本意是搜索关键字 "a&b"。但浏览器会把 & 解析为参数分隔符,导致后端接收到的 q 的值只有 "a","b" 变成了一个没有值的空参数。
编码规则是怎样的?
URL 编码的规则非常简单:
- 将字符转换为其对应的 UTF-8 字节。
- 将每个字节表示为两个十六进制数字。
- 在前面加上一个百分号
%。
例如,汉字“中”的 UTF-8 编码是 E4 B8 AD。经过 URL 编码后,它就变成了 %E4%B8%AD。
空格的 ASCII 码是 32(十六进制 20),所以空格被编码为 %20(在旧标准的 application/x-www-form-urlencoded 中,空格也常被编码为 +)。
JavaScript 中的三种编码方法
在 JS 中,我们有三个原生的编码函数,它们的作用域各不相同:
1. escape() (已废弃)
千万不要再使用它! 它使用的是非标准的 Unicode 编码,而不是 UTF-8,处理中文时极易出现乱码。
2. encodeURI()
用于对整个 URL 进行编码。
它不会对 URL 的保留字符(如 : / ? & = #)进行编码。
适用场景:当你有一个完整的网址包含中文路径时。
3. encodeURIComponent() (最常用)
用于对 URL 的参数值(Component)进行编码。
它会对所有保留字符进行编码。
适用场景:当你拼接 ?key=value 时,必须用它包裹 value。
const keyword = "a&b=c";
const url = `https://api.com/search?q=${encodeURIComponent(keyword)}`;
// 结果: https://api.com/search?q=a%26b%3Dc
如果您不想写代码,也可以直接使用我们提供的 在线 URL 编解码工具 进行快速转换!