fetch() 不支持直接用 compressionstream 压缩请求体,因所有主流浏览器截至 2026 年 5 月均未实现 readablestream 作为 body 的规范;唯一稳定方案是预压缩为 blob 并手动设置 content-encoding: gzip。

不能直接用 CompressionStream 压缩 fetch() 的请求体 —— 因为 fetch() 不接受流式请求体(ReadableStream)作为 body,除非是 FormData、Blob、URLSearchParams 或字符串等有限类型。
为什么 fetch(body: ReadableStream) 会失败
尽管 fetch() 规范理论上支持 ReadableStream 作为 body,但截至 2026 年 5 月,Chrome、Firefox、Edge 和 Safari **均未实现该能力**。传入 new CompressionStream("gzip").readable 或任何自建 ReadableStream,会立即抛出 TypeError: Failed to execute 'fetch': body is a ReadableStream, but streams are not supported yet(或类似提示)。
- 这是浏览器底层网络栈的硬限制,不是代码写法问题
-
fetch()当前只允许“一次性”提交的 body:它必须能被完整读取并复制进网络层,无法边压边发 -
CompressionStream输出的是ReadableStream,天然不兼容这个约束
可行替代路径:用 Blob + 预压缩代替流式压缩
若你控制后端且需 gzip 请求体(例如上传大 JSON 或日志),唯一稳定方案是:先完成压缩,再把结果转成 Blob 提交。这不是“流式”,但可规避兼容性陷阱。
- 用
new TextEncoder().encode(str)将原始数据转为Uint8Array - 用
ReadableStream.from(uint8array).pipeThrough(new CompressionStream("gzip"))得到压缩流 - 用
await stream.getReader().read()收集所有Uint8Array块,拼成完整 gzip 字节(含 RFC 1952 头尾) - 调用
new Blob([finalUint8Array], { type: "application/gzip" }) - 传给
fetch(url, { method: "POST", body: blob })
注意:Content-Encoding: gzip 必须由后端主动识别并解压 —— 浏览器不会自动设置该 header,也**不会**因 body 是 gzip 而自动加它。你得手动加:headers: { "Content-Encoding": "gzip", "Content-Type": "application/json" }(类型按实际 payload 设)。
服务端必须显式解压,前端不代劳
即使你成功发出了 gzip body,fetch() 不会帮你协商或声明压缩;它只管发字节。这意味着:
- 后端收到的是裸 gzip 二进制,不是自动解压后的原始数据
- Node.js(Express/Fastify)、Python(FastAPI/Flask)、Java(Spring)等框架默认**不解析
Content-Encoding**,需手动接入解压中间件 - 若后端没解压,你拿到的就是乱码或解析失败(如 JSON.parse 报错
Unexpected token \x1f) - 别指望 Nginx/Apache 自动解压请求体 —— 它们只处理响应压缩,对请求体 gzip 默认透传
真正流式上传的现实选择只有 Fetch + Service Worker 或 WebTransport
如果你的场景强依赖“边采边压边传”(如实时音视频元数据、传感器流),fetch() 无解。可考虑:
-
Service Worker拦截请求:在 SW 里用CompressionStream处理event.request.body(它支持流),再用fetch(event.request.url, { ... })转发 —— 但要求你的页面已注册 SW,且用户已访问过 -
WebTransport(Chrome/Edge 120+):原生支持双向流,可手写压缩逻辑 + 自定义协议头,但目前无 gzip 内置支持,需自己实现 deflate 编码(用pako等库) - 降级回
XMLHttpRequest?不行 —— 它也不支持流式 body,且已废弃
最常被忽略的一点:所谓“前端 gzip 上传”,99% 的真实需求其实只是“减小上传体积”,而预压缩 + Blob 已足够 —— 真正需要毫秒级流控的场景,早该换协议了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











