URL 编码是什么
URL 编码(百分号编码,percent-encoding)由 RFC 3986 定义:把 URL 中的保留字符、不安全字符与非 ASCII 字符转换为 %XX 形式的十六进制字节。中文字符需要先按 UTF-8 编码,再逐字节转义,所以一个汉字通常变成三段 %XX。查询参数拼接、接口签名串构造、重定向地址传递都依赖这套规则,它也是接口验签失败与参数错乱的高频原因。
基本信息
| 标准 | RFC 3986(URI 通用语法) |
|---|---|
| 空格的两种写法 | 路径中通常写 %20,表单查询串中可用 + |
| 非 ASCII | 先按 UTF-8 编码,再逐字节转义 |
| 保留字符 | : / ? # [ ] @ ! $ & ' ( ) * + , ; = 是否转义取决于所处位置 |
| 大小写 | %XX 中的十六进制字母大小写等价,但签名需按对端约定统一 |
典型使用场景
- 拼接带中文或含 & 与 = 的查询参数,否则参数会被截断或错位
- 构造 API 签名串:排序、拼接、编码的顺序必须与文档一致
- 生成带返回地址的跳转链接,returnUrl 需要整体编码后再作为参数传递
- 处理表单提交,application/x-www-form-urlencoded 把空格编码为 +
- 排查日志里 404 的路径:多半是编码缺失、路径段未转义或双重编码
编码与解码示例
编码与解码示例
import urllib.parse
print(urllib.parse.quote('中文 值')) # %E4%B8%AD%E6%96%87%20%E5%80%BC
print(urllib.parse.quote_plus('a b&c')) # a+b%26c(空格转 +)
print(urllib.parse.urlencode({'q': '中文'})) # q=%E4%B8%AD%E6%96%87
print(urllib.parse.unquote('%E4%B8%AD')) # 中(解码还原)
# quote 默认不转义 / ,处理路径段时要显式传 safe=''
# 命令行快速验证:curl -G --data-urlencode 'q=中文' https://example.com/search编码不一致的症状
| 症状 | 常见原因 | 处理方式 |
|---|---|---|
| 参数值被截断 | 值里的 & 未编码 | 对每个值单独编码后再拼接 |
| 结果出现 %2520 | 入参已被编码,代码又编码一次 | 在出口统一做一次编码 |
| 验签失败 | 编码顺序或字符集与文档不符 | 按排序→拼接→编码→签名执行 |
| 中文乱码 | 未按 UTF-8 编码后转义 | 全链路统一 UTF-8 |
签名类接口的要求是「参数排序 → 拼接 → 统一编码 → 计算签名」,顺序错一步就会验签失败,而且报错往往只说签名不匹配。调试时把编码后的原始串打印出来,与文档逐字符比对,比反复猜测参数更快。