返回博客列表

彻底搞懂 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 编码的规则非常简单:

  1. 将字符转换为其对应的 UTF-8 字节
  2. 将每个字节表示为两个十六进制数字。
  3. 在前面加上一个百分号 %

例如,汉字“中”的 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 编解码工具 进行快速转换!