JavaScript如何解压WebSocket zlib deflate消息供JSON.parse使用
zlib deflate压缩WebSocket消息的正确解压方法
问题根因
你之前的操作存在几个核心错误:
- 压缩/解压方向搞反:服务端推送的是deflate算法压缩后的二进制数据,需要做inflate解压操作,你之前调用
pako.deflate()是对收到的数据再次执行压缩,逻辑完全反向 - 直接解码未解压数据:未解压的二进制流不是UTF-8编码的文本,直接用
TextDecoder解码必然得到乱码 - 代码笔误:你
onmessage绑定的回调函数名是digifinex_trades,但实际定义的函数名为fu_bitmex_trades,会导致回调无法正常触发
你收到的数据首字节120(即十六进制0x78)、第二字节-38(转无符号值为218,即十六进制0xDA),是标准zlib deflate压缩流的头部标记,和接口文档标注的压缩格式完全匹配。
正确处理步骤
- 保持WebSocket的
binaryType设为arraybuffer的配置不变 - 收到二进制消息后,先将ArrayBuffer转为Uint8Array类型,传入
pako.inflate()执行解压,得到解压后的二进制数据 - 用UTF-8编码的TextDecoder将解压后的二进制数据转为普通字符串
- 对字符串调用
JSON.parse()即可得到可直接使用的JS对象/数组
修正后可直接运行的代码
// 若通过CDN引入pako可省略import语句,直接使用全局pako对象 import pako from 'pako'; const digifinexopen = '{"id":12312,"method":"trades.subscribe","params":["btc_usdt"]}'; const digifinex_market_ws = new WebSocket("wss://openapi.digifinex.com/ws/v1/"); digifinex_market_ws.binaryType = "arraybuffer"; function digifinex_trades(data) { // 转换为pako可处理的Uint8Array格式 const compressedData = new Uint8Array(data); try { // 执行zlib解压 const decompressedData = pako.inflate(compressedData); // 转换为UTF-8文本 const jsonString = new TextDecoder("utf-8").decode(decompressedData); // 解析为JS对象 const result = JSON.parse(jsonString); console.log('解析后的消息:', result); } catch (err) { console.error('解压/解析失败:', err); } } digifinex_market_ws.onmessage = event => digifinex_trades(event.data); digifinex_market_ws.onopen = event => digifinex_market_ws.send(digifinexopen);
异常兼容说明
如果遇到incorrect header check类的解压报错,可将pako.inflate替换为pako.inflateRaw尝试,极少数场景下会传输去掉zlib头的raw deflate数据,但根据你提供的头字节判断,当前场景用标准pako.inflate即可正常处理。
内容的提问来源于stack exchange,提问作者John R
相关产品推荐
相关产品推荐

