核心答案:URL 编码把不安全字符转成 %XX(十六进制字节值)——空格变 %20、中文"你"变 %E4%BD%A0(UTF-8 三字节)。JS 用 encodeURIComponent 编码参数值,encodeURI 编码整个 URL。
URL 编码原理
URL 只允许:字母、数字、− _ . ~ 四个符号。其他一律转义为 % + 两位十六进制(按 UTF-8 字节)。
| 字符 | 编码 | 原因 |
|---|---|---|
| 空格 | %20(查询串中可用 +) | 不安全字符 |
| & | %26 | 参数分隔符 |
| = | %3D | 键值分隔符 |
| # | %23 | 锚点符 |
| ? | %3F | 查询起始符 |
| / | %2F | 路径分隔符 |
| % | %25 | 转义符本身 |
| 你 | %E4%BD%A0 | UTF-8 三字节 |
保留字符对照表
保留字符(有特殊语法意义,作为数据时必须编码):
: / ? # [ ] @ ! $ & ' ( ) * + , ; =
经典事故:搜索 "C&A" 不编码 → /search?q=C&A → 参数 A 被当新参数。
encodeURI vs encodeURIComponent
| 函数 | 不编码 | 用途 |
|---|---|---|
| encodeURI | : / ? & = # 等保留字符 | 编码完整 URL |
| encodeURIComponent | 几乎全编码 | 编码参数值 |
```js
// 正确:参数值用 encodeURIComponent
const url = '/search?q=' + encodeURIComponent('C&A 教程');
// /search?q=C%26A%20%E6%95%99%E7%A8%8B
// 错误:整个 URL 用 encodeURIComponent,:// 都被编码
```
中文与空格
- 中文按 UTF-8 每字 3 字节:你 → E4 BD A0 → %E4%BD%A0
- 空格两派:query string 传统用 +(application/x-www-form-urlencoded),路径部分必须 %20
- 解码:decodeURIComponent 会把 + 还原成空格(在查询串上下文)
常见误区
- 双重编码:编码后的串再编码一次 %20→%2520——检查是否框架已自动编码。
- 路径段拼接不编码:用户输入含 / 会篡改路径结构(/user/../admin)。
- 编码整个 URL:encodeURIComponent(整串) 把 :// 都破坏。
- 后端忘记解码:拿到 %E4%BD%A0 直接存库——用框架的 query 解析自动解码。
用[URL 编解码工具](/c/dev/url-codec)一键编码/解码并预览 UTF-8 还原结果。