Python3 websocket-client解压base64响应报incorrect header check错误
WebSocket响应乱码、zlib/gzip解压报头错误排查方案
报错根因
你遇到的Error -3 while decompressing data: incorrect header check是解压参数和实际压缩流格式不匹配导致的:
- gzip格式要求流开头必须是魔数
0x1f 0x8b,你的数据开头为0x80 0x00,不符合gzip格式要求,必然解压失败 - 标准zlib格式要求流开头带2字节zlib头(常见为
0x78开头),你拿到的是WebSocketpermessage-deflate扩展生成的raw deflate流,不带zlib头、不带尾部校验值,用zlib默认参数解压也会触发报头错误 - 压缩流中夹杂
code、onlinePlayers这类明文字符串是deflate算法的正常表现:LZ77压缩逻辑中,首次出现、无法从历史滑动窗口匹配到的短字符串会以字面量形式直接写入压缩流,不代表数据未压缩。
最优解决方案:开启客户端自动解压
websocket-client库内置了permessage-deflate扩展支持,开启后会自动处理压缩协商、解压逻辑,不需要手动处理字节流,示例代码:
import websocket from websocket.extensions.permessage_deflate import PerMessageDeflateExtension # 建立连接时传入压缩扩展 ws = websocket.create_connection( "wss://你的目标服务地址", extensions=[PerMessageDeflateExtension()] ) # 直接调用recv即可拿到解压后的明文内容 resp = ws.recv() print(resp)
手动解压实现
如果受限于websocket-client版本无法使用内置扩展,可以按照permessage-deflate规范手动解压,注意两个核心要点:
- 使用raw deflate模式初始化zlib解压器,
wbits参数设为-15 - 手动补充规范中要求省略的deflate结束块
b'\x00\x00\xff\xff',否则会提示数据不完整
示例代码:
import zlib import base64 b64_resp = "gABQEgADAAFwEgACAAFwEgACAARjb2RlBAAAAMgADW9ubGluZVBsYXllcnMFAAAAAAAAAqQAAWMIAA1vbmxpbmVQbGF5ZXJzAAFhAwANAAFjAgE=" raw_compressed = base64.b64decode(b64_resp) # 初始化raw deflate解压器 decompressor = zlib.decompressobj(-zlib.MAX_WBITS) plain_data = decompressor.decompress(raw_compressed) # 补充结束块完成解压 plain_data += decompressor.decompress(b'\x00\x00\xff\xff') # 输出明文,此前为JSON格式的话直接解码即可 print(plain_data.decode("utf-8"))
额外说明
如果按上述步骤解压后得到的仍是二进制内容而非可读JSON,说明服务端在压缩前额外使用了Protobuf/MessagePack等二进制序列化协议,需要根据服务端采用的序列化协议对应反序列化即可。从你描述的此前直接转utf-8即可正常解析的情况判断,开启自动解压后即可直接得到可读明文。
内容的提问来源于stack exchange,提问作者Lucas016
相关产品推荐
相关产品推荐

