
httpx 不会自动对 url 字符串中的 `+` 号进行百分号编码,导致巴西 pix 二维码等含特殊符号的参数解析失败;正确做法是使用 `params=` 参数而非手动拼接 url,由 httpx 内部调用 `urllib.parse` 完成标准化编码。
在使用 HTTPX 发起 GET 请求时,若直接将查询参数拼接到 URL 字符串中(如 httpx.get(url + '?qrcode=' + data)),HTTPX 不会对 +、空格等字符做额外编码处理——因为其底层 URL 解析逻辑将 + 视为“安全字符”(safe='!$&\'()*+,;=:/?[]@'),默认不转义。这会导致银行 API(如巴西 BACEN PIX 接口)收到未编码的 +,可能被误解析为空格或引发协议校验失败。
✅ 正确做法:始终使用 params 关键字参数传递查询参数:
import httpx url = "https:///qrcode" data = "00020101021126360014br.gov.bcb.pix0114+55489962650955204000053039865802BR5925TEREZINHA APARECIDA DEL S6008BRASILIA62070503***63040833" # ✅ 推荐:由 HTTPX 自动编码(+ → %2B,空格 → %20) response = httpx.get(url, params={"qrcode": data}) print(response.url) # 输出示例:https:// /qrcode?qrcode=00020101021126360014br.gov.bcb.pix0114%2B55489962650955204000053039865802BR5925TEREZINHA%20APARECIDA%20DEL%20S6008BRASILIA62070503***63040833
⚠️ 注意事项:
- 手动拼接 URL(如 url + '?qrcode=' + data)绕过了 HTTPX 的参数编码机制,需自行调用 urllib.parse.quote(),但易出错且不可维护;
- params 支持字典、列表(用于多值参数)或 urllib.parse.urlencode() 返回的字符串,推荐字典形式;
- + 在 URL 查询字符串中本应表示空格(遵循 application/x-www-form-urlencoded 规范),但 PIX QR Code 原始 payload 中的 + 是电话号码的一部分(如 +5548...),必须保留字面意义,因此必须编码为 %2B;
- 同一问题在 requests 库中同样存在——这不是 HTTPX 的 Bug,而是所有主流 HTTP 客户端对「手动拼接」与「参数化构建」URL 的明确区分。
? 总结:永远优先使用 params= 而非字符串拼接来传递查询参数。这不仅确保 +、空格、/、? 等字符被正确编码,还提升代码可读性、安全性(防注入)和跨平台兼容性。对于巴西 PIX 场景,这是符合 BACEN 技术规范(PIX Standard v2.3+)的必备实践。










