如何让aiohttp兼容返回拼接响应的缺陷HTTP服务器?
解决aiohttp 3.8.6+对接返回拼接响应的缺陷服务器问题
针对你遇到的缺陷服务器返回拼接HTTP响应,导致aiohttp 3.8.6及以上版本抛出异常的问题,有以下几种可行的解决办法:
方法1:按Content-Length读取精确内容
既然服务器返回的第一个响应头里包含正确的Content-Length,直接读取对应长度的内容即可忽略后续的多余数据,这是最可靠的方案:
import aiohttp import json async def get_dimmer_data(): target_url = "http://192.168.8.204/getminiteur?dimmer" async with aiohttp.ClientSession() as session: async with session.get(target_url) as resp: # 从响应头获取Content-Length值 content_len = int(resp.headers.get("Content-Length", 0)) if content_len > 0: # 读取精确长度的响应内容 raw_content = await resp.content.readexactly(content_len) return json.loads(raw_content.decode("utf-8")) # 兼容没有Content-Length的情况(按需调整) raw_content = await resp.content.read() return json.loads(raw_content.decode("utf-8"))
方法2:捕获异常并提取部分数据
aiohttp抛出的ClientPayloadError中会保留已读取的部分数据,你可以捕获这个异常并解析已获取的内容:
import aiohttp from aiohttp import ClientPayloadError import json async def get_dimmer_data(): target_url = "http://192.168.8.204/getminiteur?dimmer" async with aiohttp.ClientSession() as session: try: async with session.get(target_url) as resp: return await resp.json() except ClientPayloadError as e: # 从异常对象中提取已读取的部分数据 if hasattr(e, "_partial") and e._partial: partial_content = e._partial.decode("utf-8") return json.loads(partial_content) # 如果无法提取部分数据,再抛出异常 raise
注意:这个方法依赖aiohttp内部异常的结构,后续版本可能会有变化,需要做好兼容性测试。
方法3:降级aiohttp版本到3.8.5
如果上面的方法都不适用,最直接的临时方案是降级到之前能正常工作的版本:
pip install aiohttp==3.8.5
但这种方式会错过新版本的功能和安全修复,仅作为备选方案。
内容的提问来源于stack exchange,提问作者Benjamin Renard
相关产品推荐
相关产品推荐

