浏览器 fetch 会自动解压 gzip/br/deflate 响应,response.body 及 text()/json() 等方法返回的已是解压后数据,无需也不应手动解压。

浏览器中的 fetch 会自动解压后端返回的 gzip(或 deflate、br)压缩响应,你无需手动处理压缩流 —— 这是浏览器底层网络层(如 Chromium 的网络栈)完成的,对 JavaScript 完全透明。
浏览器自动解压,response.body 已是解压后数据
只要服务器在响应头中正确设置了:
-
Content-Encoding: gzip(或其他支持的编码,如br、deflate) - 且请求头中包含
Accept-Encoding: gzip, br, deflate(fetch 默认自带)
那么 fetch 返回的 Response 对象中:
-
response.headers.get('content-encoding')可能仍为"gzip"(表示原始传输编码) -
await response.text()、await response.json()、await response.arrayBuffer()等方法返回的,**已经是解压后的原始内容** -
response.body(ReadableStream)读取的也是解压后的字节流
不需要也不应该手动解压
你不能也不该在 JS 中用 pako 或 fflate 去“再解一次”响应体 —— 因为它早已被浏览器解压过了。常见误操作包括:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 看到
content-encoding: gzip就以为 body 是压缩数据,试图用pako.inflate()处理arrayBuffer→ 报错或乱码 - 用
response.body管道接DecompressionStream(如new DecompressionStream('gzip'))→ 浏览器不支持该构造函数(目前仅部分浏览器实验性支持,且仅适用于你主动压缩的流,不用于已解压的响应体)
✅ 正确做法:直接按常规方式消费响应即可:
const res = await fetch('/api/data');
const data = await res.json(); // 自动解压 + JSON 解析
console.log(data); // 拿到的是原始 JSON 数据,不是 gzip 字节
如何确认是否真的用了 gzip?
检查 Network 面板中的响应头和「Size / Transferred」列:
- 若
Content-Encoding: gzip存在,且 “Transferred” 明显小于 “Size”(例如 2KB transferred vs 10KB size),说明压缩生效 - 在代码中可通过
res.headers.get('content-encoding')判断是否启用了压缩,但注意:即使有该 header,body 内容也已是解压态
服务端需确保正确配置
前端无须干预,但后端必须正确设置:
- 开启 gzip 压缩中间件(如 Express 的
compression()、Nginx 的gzip on) - 避免对已压缩资源(如 .jpg/.png/.gz 文件)重复压缩
- 确保
Vary: Accept-Encoding响应头存在,以便 CDN 和代理正确缓存
只要服务端配对、浏览器支持(所有现代浏览器均支持自动解压 gzip/br),fetch 就会静默完成解压,开发者完全无感。

















