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

如何让aiohttp.ClientSession忽略或接受含空格的响应头?

解决aiohttp因响应头含空格抛出的Invalid header token错误

针对API返回含空格的响应头(如Status Code: 200)导致aiohttp解析失败的问题,提供两种可行的临时解决方案:

方案一:全局修改头部解析规则,允许空格

通过monkey patch修改aiohttp内部的头部字符校验逻辑,让它接受空格作为头部名称的一部分:

import aiohttp
from aiohttp.http_parser import _is_token

# 保存原始校验函数
original_is_token = _is_token

# 重写校验逻辑,允许空格字符
def patched_is_token(c: int) -> bool:
    if c == ord(' '):
        return True
    return original_is_token(c)

# 替换原函数
aiohttp.http_parser._is_token = patched_is_token

# 正常发起请求
async def fetch_data():
    async with aiohttp.ClientSession() as session:
        async with session.get("https://目标API地址") as resp:
            print(f"状态码: {resp.status}")
            print("响应头:", dict(resp.headers))

优缺点:实现简单,所有含空格的头部都会被正常解析,但违反HTTP规范,可能带来潜在的兼容性风险。

方案二:自定义解析器,跳过解析失败的头部

创建自定义的响应解析器,捕获头部解析错误并跳过有问题的条目,不影响其他正常头部:

import aiohttp
from aiohttp.http_parser import HttpResponseParser

class TolerantHttpResponseParser(HttpResponseParser):
    def _parse_header(self, line: bytes) -> tuple[bytes, bytes] | None:
        try:
            # 尝试用原始逻辑解析头部
            return super()._parse_header(line)
        except ValueError:
            # 解析失败时跳过该头部
            return None

# 使用自定义解析器创建连接器
connector = aiohttp.TCPConnector(response_parser=TolerantHttpResponseParser)

# 发起请求
async def fetch_data():
    async with aiohttp.ClientSession(connector=connector) as session:
        async with session.get("https://目标API地址") as resp:
            print(f"状态码: {resp.status}")
            print("响应头:", dict(resp.headers))

优缺点:仅跳过解析失败的头部,不会全局修改HTTP规范的校验逻辑,安全性更高,但需要自定义解析器类。

注意事项

  • 以上方案针对aiohttp 3.10.5版本有效,后续版本内部实现若有变更,需对应调整代码。
  • 这两种方法均为临时 workaround,核心问题是API违反HTTP规范,建议优先推动API提供方修复响应头格式问题。

内容的提问来源于stack exchange,提问作者Matthew Young

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 08:52:17