
什么是URL编码?
URL编码(也称为百分号编码)将URL中不允许的字符转换为可以在互联网上安全传输的格式。该过程将不安全字符替换为百分号(%)后跟两个十六进制数字,表示该字符的ASCII或UTF-8代码。
每个URL必须仅由一组定义的安全字符组成。超出该集合的任何字符都必须编码。

为什么URL有受限字符
URI规范(RFC 3986)将字符分为三类:
- 保留字符在URI中具有特殊含义:
: / ? # [ ] @ ! $ & ' ( ) * + , ; = - 非保留字符始终安全:
A-Z a-z 0-9 - _ . ~ - 所有其他字符必须进行百分号编码
如果保留字符出现在查询参数值中,则必须编码。否则,解析器会将其误解为结构分隔符。
百分号编码的工作原理
空格 = 0x20 -> %20
! = 0x21 -> %21
# = 0x23 -> %23
& = 0x26 -> %26
+ = 0x2B -> %2B(字面加号)
= = 0x3D -> %3D
? = 0x3F -> %3F
@ = 0x40 -> %40
多字节UTF-8字符被编码为多个百分号序列:
é = UTF-8 0xC3 0xA9 -> %C3%A9
中 = UTF-8 0xE4 0xB8 0xAD -> %E4%B8%AD

URL编码与表单编码
有两种相关但不同的编码方案。百分号编码(RFC 3986)将空格转换为%20,用于路径段和严格的URI一致性。application/x-www-form-urlencoded将空格转换为+,用于HTML表单提交。它们的编码规则略有不同。
// 百分号编码(标准)
encodeURIComponent('hello world') // 'hello%20world'
// 表单编码(空格为+)
new URLSearchParams({ q: 'hello world' }).toString() // 'q=hello+world'
JavaScript URL编码函数
JavaScript有四个用于URL编码和解码的函数:
| 函数 | 编码内容 | 使用场景 |
|---|---|---|
encodeURI |
除未保留字符和结构字符外的所有字符 | 编码完整URL |
encodeURIComponent |
除未保留字符外的所有字符 | 编码查询参数、路径段 |
decodeURI |
反转encodeURI | 解码完整URL |
decodeURIComponent |
反转encodeURIComponent | 解码URL组件 |
// 编码完整URL - 保留结构字符
encodeURI('https://example.com/path?q=hello world')
// 'https://example.com/path?q=hello%20world'
// 编码查询参数值
encodeURIComponent('hello world & more')
// 'hello%20world%20%26%20more'
// 解码
decodeURIComponent('hello%20world') // 'hello world'

常见URL编码示例
Web开发中最常编码的字符有:空格变为%20,井号变为%23(在查询值中使用%23,因为#是片段分隔符),与号变为%26(在查询值中使用%26,因为&分隔参数),加号变为%2B(用于字面加号),正斜杠变为%2F(用于路径段中的字面斜杠),等号变为%3D(在参数值内部)。
URL结构及编码应用位置
https://example.com:8080/path?key=value&foo=bar#section
每个部分有不同的编码规则。路径段应对除未保留字符和斜杠分隔符之外的所有内容进行编码。查询参数应对与号、等号、加号、百分号等进行编码。片段遵循与查询编码类似的规则。
国际化URL
现代浏览器以Unicode形式显示国际化域名和路径,但在传输时进行编码。例如,路径中包含中文字符的URL在浏览器中会正常显示,但传输时作为百分号编码的UTF-8字节。域名使用Punycode(xn--)编码处理非ASCII字符。
-> 试试 URL编码/解码工具