You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Requests发送HTTP POST时TCP包拆分致API请求失败排查

解决Python requests/urllib3 POST请求因数据包拆分报错的问题

这个问题我之前也碰到过,大概率是目标API**不支持HTTP分块传输编码(Chunked Transfer Encoding)**导致的!

问题根源

curl默认会提前计算请求体的总长度,设置Content-Length头部,把整个请求打包成单一数据包发送;而Python的requests/urllib3当请求体大小超过内部阈值(通常是1KB左右)时,会自动启用分块传输,将请求体拆分成多个数据包发送。很多老旧或者实现不规范的API无法正确解析分块传输的请求,所以会返回错误响应。

解决方案:强制禁用分块传输

下面针对不同库给出具体实现:

1. 使用requests库的两种方法

方法一:自定义适配器全局禁用分块
import requests
from requests.adapters import HTTPAdapter

class NoChunkAdapter(HTTPAdapter):
    def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None):
        # 移除分块传输的头部
        request.headers.pop('Transfer-Encoding', None)
        # 手动计算并设置Content-Length
        if request.body is not None:
            request.headers['Content-Length'] = str(len(request.body))
        return super().send(request, stream, timeout, verify, cert, proxies)

# 初始化会话并挂载适配器
session = requests.Session()
session.mount('https://your-api-domain.com', NoChunkAdapter())

# 发送请求
payload = {"key1": "value1", "key2": "value2"}
headers = {"Content-Type": "application/json", "X-Custom-Header": "your-value"}
response = session.post('https://your-api-domain.com/target-endpoint', json=payload, headers=headers)

print(response.status_code)
print(response.text)
方法二:手动序列化JSON并设置Content-Length
import requests
import json

payload = {"key1": "value1", "key2": "value2"}
# 手动序列化JSON,避免requests自动处理
json_payload = json.dumps(payload)
headers = {
    "Content-Type": "application/json",
    # 计算并设置内容长度
    "Content-Length": str(len(json_payload))
}

response = requests.post(
    'https://your-api-domain.com/target-endpoint',
    data=json_payload,
    headers=headers,
    # 禁用流式传输(避免分块)
    stream=False
)

print(response.status_code)
print(response.text)

2. 使用urllib3库的解决方案

import urllib3
import json

payload = {"key1": "value1", "key2": "value2"}
json_payload = json.dumps(payload)
headers = {
    "Content-Type": "application/json",
    "Content-Length": str(len(json_payload))
}

http = urllib3.PoolManager()
response = http.request(
    'POST',
    'https://your-api-domain.com/target-endpoint',
    body=json_payload,
    headers=headers,
    # 明确禁用分块传输
    chunked=False
)

print(response.status)
print(response.data.decode('utf-8'))

验证方式

修改代码后,再用Wireshark抓包,确认Python发送的请求是单一数据包,且包含正确的Content-Length头部,没有Transfer-Encoding: chunked字段,这样就和curl的请求格式一致了,API应该就能正常响应。

内容的提问来源于stack exchange,提问作者Christian H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:50:26