如何在Python Requests库中设置Transfer-Encoding:chunked请求头?
解决Requests库无法发送
Transfer-Encoding: chunked请求的问题 问题根源
Requests库会自动管理HTTP请求的Content-Length和Transfer-Encoding头:当它能计算出请求体的总长度(比如你的生成器内容可被完整遍历),就会优先添加Content-Length并忽略你显式设置的Transfer-Encoding: chunked。此外,你手动构造的chunk分块格式(如8\r\n)也不符合Requests的预期——它会自动处理chunk编码的分块逻辑,不需要你手动添加长度标识和换行。
解决方案1:手动构造PreparedRequest强制启用chunked
通过直接操作PreparedRequest,在请求准备完成后修改请求头,移除自动添加的Content-Length并强制设置Transfer-Encoding:
import requests from requests.models import PreparedRequest url = 'http://[replaced]/test.php' def data_chunks(): # 仅返回实际业务数据,无需手动处理chunk分块格式 yield b'search=1' # 初始化请求对象 req = requests.Request( 'POST', url, data=data_chunks(), headers={"Content-Type": "application/x-www-form-urlencoded"} ) # 准备请求 prepped = req.prepare() # 强制设置chunked编码,移除自动生成的Content-Length prepped.headers["Transfer-Encoding"] = "chunked" prepped.headers.pop("Content-Length", None) # 发送请求 with requests.Session() as sess: response = sess.send(prepped, proxies={"http": "http://127.0.0.1:8080"})
解决方案2:直接使用底层urllib3库
如果需要完全自定义chunk分块格式,可以绕过Requests,直接使用其底层依赖urllib3——它不会自动替换Transfer-Encoding头,支持完全自定义的chunk生成器:
import urllib3 url = 'http://[replaced]/test.php' http = urllib3.PoolManager() def chunk_generator(): # 严格按照HTTP chunked格式构造内容,最后需额外添加\r\n结束 yield b'8\r\n' yield b'search=1\r\n' yield b'0\r\n\r\n' response = http.request( 'POST', url, body=chunk_generator(), headers={ "Content-Type": "application/x-www-form-urlencoded", "Transfer-Encoding": "chunked" }, proxies={"http": "http://127.0.0.1:8080"} )
关键说明
- 若使用Requests的原生
post方法,只要请求体长度可被计算(包括生成器内容可被完整遍历),它就会自动添加Content-Length,这是库的默认优化逻辑。 - 手动构造chunk格式时,必须遵循HTTP规范:每个分块以
十六进制长度\r\n开头,内容\r\n结尾,最后以0\r\n\r\n标识结束。
内容的提问来源于stack exchange,提问作者Green
相关产品推荐
相关产品推荐

