URL参数中的空格、加号和&,用Python一次编码正确

举报
yd_283252214 发表于 2026/10/19 01:58:33 2026/10/19
【摘要】 用Python标准库urlencode与parse_qs验证中文、空格、加号、&和空值的查询参数编码,说明为什么要保留原始值并避免重复编码。

给接口拼接查询参数时,如果把用户输入直接放到 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 序列化规则。示例代码与说明为独立编写。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。