在Python的网络请求场景中,httpx是目前少有的原生支持HTTP/2的常用HTTP客户端库,用它发送HTTP/2 POST请求并不复杂,下面我们一步步梳理完整实现过程。

环境准备
首先需要确保安装的httpx版本支持HTTP/2,官方从0.18.0版本开始原生支持HTTP/2,不需要额外安装其他依赖,直接用pip安装最新版即可:
# 安装httpx pip install httpx
安装完成后可以简单验证是否支持HTTP/2,通过导入库后查看相关属性即可,不过实际发送请求时如果服务端支持HTTP/2,httpx会自动协商使用对应协议。
发送基础HTTP/2 POST请求
httpx的Client类可以配置是否启用HTTP/2,默认情况下httpx会尝试与服务端协商使用HTTP/2,我们只需要创建客户端时显式开启HTTP/2支持即可,下面是发送JSON格式POST请求的基础示例:
import httpx
# 创建支持HTTP/2的客户端,http2参数设为True
with httpx.Client(http2=True) as client:
# 定义请求地址,这里使用一个支持HTTP/2的测试地址
url = "https://http2.pro/api/v1"
# 定义POST请求的JSON请求体
payload = {"test_key": "test_value"}
# 发送POST请求
response = client.post(url, json=payload)
# 打印响应结果
print(f"响应状态码: {response.status_code}")
print(f"响应内容: {response.text}")
# 查看实际使用的协议版本
print(f"使用的协议版本: {response.http_version}")运行上述代码后,如果服务端支持HTTP/2,你会发现response.http_version的输出是HTTP/2,说明已经成功使用HTTP/2协议发送了POST请求。
自定义请求头与请求体
实际开发中往往需要自定义请求头,或者发送表单格式、原始数据格式的请求体,httpx都提供了对应的参数支持,下面是发送表单格式POST请求的示例:
import httpx
with httpx.Client(http2=True) as client:
url = "https://ipipp.com/post-test"
# 自定义请求头
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept": "application/json"
}
# 表单格式的请求体
data = {
"username": "test_user",
"password": "test_pass"
}
response = client.post(url, data=data, headers=headers)
print(f"状态码: {response.status_code}")
print(f"协议版本: {response.http_version}")
print(f"响应JSON: {response.json()}")异常处理与超时设置
发送网络请求时难免会遇到连接失败、超时等问题,httpx提供了完善的异常类,我们可以针对性地处理不同的错误场景,同时建议设置合理的超时时间:
import httpx
try:
# 设置超时时间,连接超时5秒,读取超时10秒
timeout = httpx.Timeout(connect=5.0, read=10.0)
with httpx.Client(http2=True, timeout=timeout) as client:
url = "https://ipipp.com/slow-api"
payload = {"query": "test"}
response = client.post(url, json=payload)
response.raise_for_status() # 如果状态码不是2xx,抛出HTTPStatusError
print(f"请求成功,协议版本: {response.http_version}")
except httpx.ConnectError:
print("连接服务端失败,请检查网络或服务地址")
except httpx.TimeoutException:
print("请求超时,请稍后重试")
except httpx.HTTPStatusError as e:
print(f"请求失败,状态码: {e.response.status_code}")注意事项
- 不是所有服务端都支持HTTP/2,如果服务端仅支持HTTP/1.1,即使客户端开启了http2=True,也会自动降级使用HTTP/1.1协议,不会对请求造成影响。
- 如果不需要连接复用,也可以直接使用
httpx.post()快捷方法,同样可以传入http2=True参数,但这种方式每次请求都会创建新的连接,高频请求场景下建议使用Client上下文管理器。 - 发送HTTPS请求时,httpx默认会验证SSL证书,如果是测试环境使用自签名证书,可以传入
verify=False参数跳过验证,但生产环境不建议这样做。