如何用原生JS解压NodeJS中zlib压缩的数据?(pako/fflate报错)
在Vanilla JS中解压Node.js zlib压缩数据的问题解决
核心问题分析
你的代码存在两个关键问题导致解压失败:
- 十六进制字符串解码错误:直接用
fflate.strToU8()处理十六进制字符串会把每个字符转成UTF-8字节,而非将每两位十六进制字符解码为单个字节,导致压缩数据完全失真。 - 压缩格式不匹配:Node.js的zlib如果使用
deflate方法,生成的是原始deflate流(无zlib/gzip格式的头部和尾部),而gunzipSync/unzlibSync分别需要标准gzip格式(带头尾)和zlib格式(带2字节头+4字节尾),直接调用会因格式不兼容报错。
解决方案
1. 修复十六进制字符串解码
先实现正确的十六进制转Uint8Array工具函数:
function hexToUint8(hexStr) { const bytes = new Uint8Array(hexStr.length / 2); for (let i = 0; i < hexStr.length; i += 2) { bytes[i / 2] = parseInt(hexStr.slice(i, i + 2), 16); } return bytes; }
2. 根据压缩格式选择解压方式
方式一:直接处理原始deflate流(无需补头)
如果后端用zlib.deflate生成压缩数据,前端用fflate的unflateSync专门处理原始deflate流:
const zippedHex = '333080002363534b206588c43642621b23b14d90d8a6486c33181b00ccbe314454000000'; const compressedBytes = hexToUint8(zippedHex); // 解压原始deflate流 const uncompressedBytes = fflate.unflateSync(compressedBytes); // 转换为字符串 const result = fflate.U8ToStr(uncompressedBytes); console.log(result);
方式二:补全gzip头后用gunzip解压
如果你需要用gunzip解压,手动拼接标准gzip头部(十六进制1f8b0800000000000000)后再解压:
const zippedHex = '333080002363534b206588c43642621b23b14d90d8a6486c33181b00ccbe314454000000'; const compressedBytes = hexToUint8(zippedHex); // 生成gzip头部字节数组 const gzipHeader = hexToUint8('1f8b0800000000000000'); // 拼接头部与原始压缩数据 const gzipData = new Uint8Array([...gzipHeader, ...compressedBytes]); // 用gunzip解压 const uncompressedBytes = fflate.gunzipSync(gzipData); const result = fflate.U8ToStr(uncompressedBytes); console.log(result);
推荐方式:后端生成标准gzip格式(最省心)
修改Node.js压缩代码,直接用zlib.gzip生成标准gzip格式数据,前端无需额外处理即可用gunzipSync解压:
Node.js后端代码:
const zlib = require('zlib'); const rawData = '你的原始数据'; zlib.gzip(rawData, (err, gzipBuffer) => { if (!err) { // 将gzip二进制转十六进制字符串传给前端 const hexStr = gzipBuffer.toString('hex'); console.log(hexStr); } });
前端代码:
const zippedHex = '后端返回的gzip格式十六进制字符串'; const compressedBytes = hexToUint8(zippedHex); const uncompressedBytes = fflate.gunzipSync(compressedBytes); const result = fflate.U8ToStr(uncompressedBytes); console.log(result);
内容的提问来源于stack exchange,提问作者Burak Turna
相关产品推荐
相关产品推荐

