URL参数中的空格、加号和&,用Python一次编码正确
给接口拼接查询参数时,如果把用户输入直接放到 q= 后面,空格、加号和 & 很容易改变原本的含义。与其手工替换几个字符,更可靠的做法是把原始参数交给编码函数。
先分清原始值与查询字符串
在 application/x-www-form-urlencoded 这套编码规则中,空格通常写成 +;原始值里的加号要写成 %2B,原始值里的 & 要写成 %26。未编码的 & 常作为参数分隔符,不能拿它直接表示值的一部分。这里讨论的是查询参数的编码规则,不能把“+ 等于空格”推广到整条 URL 的所有位置。
用 Python 标准库做往返验证
下面的示例无需安装第三方库,也不会发送任何网络请求。用 urlencode 生成参数,再用 parse_qs 解码,断言取回的值与原始输入一致:
from urllib.parse import urlencode, parse_qs
samples = ["云服务器 & Python + 1", "a b", "a+b", "a&b", ""]
for value in samples:
encoded = urlencode({"q": value})
decoded = parse_qs(encoded, keep_blank_values=True)["q"][0]
assert decoded == value
print(repr(value), "->", encoded)
已运行验证的输出包括:
q=%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8+%26+Python+%2B+1
q=a+b
q=a%2Bb
q=a%26b
q=
parse_qs 的结果中,同一个参数名对应一个列表,所以示例读取 ["q"][0]。keep_blank_values=True 用于保留 q= 这样的空值;省略该参数时,空值默认可能不会保留在结果中。
接入接口时注意两件事
第一,始终从原始参数值编码一次。不要先把 + 手动换成 %2B,再把这个结果传给 urlencode;这样百分号还会被编码,得到 %252B,服务端解码一次后可能仍是 %2B,而不是预期的加号。
第二,不要把整条 URL 当作一个参数值来编码。协议、主机、路径和查询字符串有各自的结构,应由 URL 处理工具组合;已有查询参数时,也不能简单再拼一个问号。本文只展示独立查询字符串的生成,不包含任意 URL 的追加逻辑。
前端需要类似工具时,可以把参数名和值作为一对数据传给 URLSearchParams,再调用 toString()。仍应使用原始值,并按接口约定解析;不同 API 对参数格式可能有专门要求。编码用于表达数据,不能代替身份认证或加密。
参考资料:Python 官方文档 urllib.parse 中的 urlencode、parse_qs;WHATWG URL Standard 中的 URLSearchParams 与 application/x-www-form-urlencoded 序列化规则。示例代码与说明为独立编写。
- 点赞
- 收藏
- 关注作者
评论(0)