decompressionstream 仅支持 gzip/deflate/brotli 流式解压,不支持 zip 容器;zip 文件需用 jszip,base64 编码的 gzip 流才适用 decompressionstream,http 层 gzip 则由浏览器自动处理。

不能直接用 DecompressionStream 解压 ZIP 包——它只支持 gzip、deflate、brotli 三种流式压缩格式,不识别 ZIP 容器结构。后端若下发的是 ZIP 压缩包(如 .zip 文件),前端需用 JSZip 等专用库;若下发的是 Base64 编码的 gzip 字节流,则 DecompressionStream 才适用。
确认后端发的是哪种“压缩包”
这是最关键的前置判断:
- 如果响应是
Content-Type: application/zip,且文件名带.zip后缀 → 属于 ZIP 格式,DecompressionStream 无法处理,必须用JSZip - 如果响应是 Base64 字符串(如
H4sIAAAAAAA...开头),文档说明为 “gzip 压缩后 base64 编码的 JSON” → 属于纯 gzip 流,DecompressionStream 正确适用 - 如果接口返回的是
Content-Encoding: gzip的 HTTP 响应 → 浏览器已自动解压,你拿到的就是原始内容,无需手动调用 DecompressionStream
用 DecompressionStream 解压 Base64 + gzip 数据
适用于后端将 JSON 或文本先 gzip 压缩、再 base64 编码后返回的场景(常见于大配置、日志、离线数据):
- 先用
atob()将 base64 字符串转为二进制字符串,再构造Uint8Array - 用
ReadableStream.from(uint8array)创建可读流(Chrome 102+/Firefox 117+/Safari 16.4+ 支持) - 管道接入
new DecompressionStream("gzip"),再通过getReader().read()或response.body.pipeThrough()获取解压后字节 - 最后用
new TextDecoder().decode()转成字符串,再JSON.parse()(如原数据是 JSON)
用 JSZip 解压真正的 ZIP 文件
当后端返回的是标准 ZIP 包(比如用户上传的素材包、项目导出包),必须走 JSZip 流程:
- 用
fetch()获取Response.arrayBuffer(),或从<input type="file">读取File.arrayBuffer() - 传入
JSZip.loadAsync(arrayBuffer)加载 ZIP 结构 - 遍历
zip.file()列表,对每个文件调用async().nodebuffer()(二进制)或async("string")(文本)提取内容 - 中文文件名需确保后端 ZIP 打包时使用 UTF-8 编码,否则 JSZip 默认按 CP437 解析会乱码
注意事项与避坑点
几个容易出错的实际细节:
-
DecompressionStream不接受 Blob 或 ArrayBuffer,必须是 ReadableStream —— 别试图用blob.stream()处理大 ZIP,它会卡死;该 API 只适合纯压缩流 - JSZip 在 Safari iOS 上对大 ZIP(>100MB)支持较弱,建议服务端拆分或改用流式 ZIP 解析库(如 zip-stream-browser)
- 后端若用 Node.js 的
archiver生成 ZIP,请设zip.file(..., { binary: true, utf8: true })显式启用 UTF-8 文件名 - 不要混淆“HTTP 层 gzip”和“业务层 gzip”:前者由服务器自动处理,后者需前端手动解压,两者不可叠加误用
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









