一、什么是URL编码
URL编码(URL Encoding),也称为百分号编码(Percent-encoding),是一种将非ASCII字符或特殊字符转换为可在URL中安全传输的格式的机制。
为什么需要URL编码?
- URL 只能包含 ASCII 字符,但实际数据常包含中文、空格、特殊符号等。
- 对保留字符(如
?、&)若不作为分隔符使用,必须编码以防解析歧义。 - 例如,中文“上海+中國”编码后为
%E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B。
二、编码规则
遵循 RFC 3986 标准,URL 字符分为保留字符和未保留字符。
✅ 未保留字符(无需编码)
- 字母:
A-Z a-z - 数字:
0-9 - 特殊符号:
- _ . ~
⚠️ 保留字符(需编码)
:/?#[]@!$&'()*+,;=
编码方法:
- ASCII 字符:将字符的 ASCII 值转为两位十六进制,前加
%,如/→%2F。 - 非 ASCII 字符(如中文):先用 UTF-8 编码为字节序列,再对每个字节做百分号编码。
- 百分号本身:
%→%25。
三、全部字符编码表(ASCII 可打印字符)
下表列出了 ASCII 码 32~126 的所有可打印字符及其 URL 百分号编码。控制字符(0~31、127)通常不直接出现在 URL 中,如需编码也遵循 %XX 格式(如换行 %0A)。
| 字符 | 十进制 | 十六进制 | URL 编码 | 字符 | 十进制 | 十六进制 | URL 编码 |
|---|---|---|---|---|---|---|---|
| 加载中... | |||||||
四、常见非ASCII字符(UTF-8)编码示例
| 字符 | Unicode 码点 | UTF-8 字节 | URL 编码 |
|---|---|---|---|
| 中 | U+4E2D | E4 B8 AD | %E4%B8%AD |
| 文 | U+6587 | E6 96 87 | %E6%96%87 |
| 你 | U+4F60 | E4 BD A0 | %E4%BD%A0 |
| 好 | U+597D | E5 A5 BD | %E5%A5%BD |
| 🚀 | U+1F680 | F0 9F 9A 80 | %F0%9F%9A%80 |
| € | U+20AC | E2 82 AC | %E2%82%AC |
五、空格编码的特殊说明
| 场景 | 编码 | 说明 |
|---|---|---|
| URL 路径 / 查询参数(RFC 3986) | %20 | 现代标准推荐方式 |
application/x-www-form-urlencoded(表单提交) | + | HTML 表单默认使用 |
💡 建议: 在编码 URL 时,使用
%20 表示空格,用 %2B 表示加号 +,这样可以避免歧义。
六、编程实现
JavaScript
// 编码完整URL
encodeURI("https://example.com/搜索?q=hello world")
// → "https://example.com/%E6%90%9C%E7%B4%A2?q=hello%20world"
// 编码组件(查询参数)
encodeURIComponent("文件/name")
// → "%E6%96%87%E4%BB%B6%2Fname"
// 解码
decodeURIComponent("%21%40") // "!@"
Python
from urllib.parse import quote, unquote
# 编码
quote("搜索!@#", safe="")
# → '%E6%90%9C%E7%B4%A2%21%40%23'
# 解码
unquote("%E6%96%87%E4%BB%B6")
# → '文件'
PHP
// rawurlencode (RFC 3986)
rawurlencode("hello world");
// → "hello%20world"
// urlencode (表单,空格变+)
urlencode("hello world");
// → "hello+world"
七、注意事项
- 避免多次编码/解码:多次编码会导致
%2520这样的嵌套,需谨慎。 - 非ASCII字符统一使用UTF-8。
- 保留字符的差异化处理:
encodeURI()不编码; , / ? : @ & = + $;encodeURIComponent()全部编码。 - 安全考虑:服务器端需在解码后校验参数,防止绕过过滤。
八、总结
URL编码(百分号编码)的核心规则:
- 未保留字符(字母、数字、
-_.~)不编码。 - 保留字符和非ASCII字符编码为
%+ 两位十六进制。 - 非ASCII字符先转UTF-8再逐字节编码。
- 空格在RFC 3986中为
%20,表单中可为+。
掌握URL编码,避免解析错误与乱码,确保数据传输安全。