compressionstream("gzip")仅接受readablestream输入,需用blob([data]).stream()包装字符串或对象,并在https环境设置content-encoding: gzip请求头,阈值建议≥4kb,且须确保后端支持解压及流处理完整。

CompressionStream("gzip") 要求输入必须是 ReadableStream
直接传字符串、ArrayBuffer 或普通对象会报错:TypeError: Failed to construct 'CompressionStream': parameter 1 is not of type 'DOMString'。它只接受浏览器原生流(如 file.stream()、new Response().body),不支持 Node.js 的 fs.ReadStream 或 Buffer。
常见错误写法:
-
new CompressionStream("gzip").pipeTo(...)却没给上游提供流 —— 必须先有ReadableStream实例 - 试图用
JSON.stringify(obj)结果直接传入 —— 需包装成Blob([jsonStr]).stream() - 在非 HTTPS 环境(或 localhost 以外的 HTTP)调用时,部分浏览器会静默禁用该 API
压缩前必须显式设置 Content-Encoding 请求头
即使数据已用 CompressionStream 压缩,如果请求头没带 Content-Encoding: gzip,后端大概率会当作乱码解析。axios 拦截器里不能只改 config.data,还要同步补头:
- 后端必须支持解压(如 Express 需配
compression()中间件;.NET Core 要启用AddResponseCompression) - 若后端未识别该头,可能返回 415 或直接崩溃 —— 建议加兜底逻辑:仅对
Content-Type: application/json且method === "POST"的请求启用 - 别忘了检查
Accept-Encoding响应头是否含gzip,否则说明服务端没开启响应压缩,但那是另一回事
压缩体积阈值判断不能只看 JSON.stringify 后长度
JSON.stringify(data) 得到的是 UTF-16 字符串,而真实传输字节长度取决于编码(如中文在 UTF-8 下占 3 字节)。用 new Blob([str]).size 才接近真实体积:
const getByteLength = (data) => {
if (typeof data === 'string') return new Blob([data]).size;
if (typeof data === 'object' && data !== null) {
try {
return new Blob([JSON.stringify(data)]).size;
} catch {
return 0;
}
}
return 0;
};
建议阈值设为 4096(4KB)以上再压缩 —— 小于这个量级,Gzip 头部开销反而可能让体积变大。
后端解压失败?重点查三件事
前端压缩成功但后端收不到原始数据,大概率不是压缩问题,而是流处理链断裂:
-
CompressionStream输出的是ReadableStream,axios 默认不支持直接传流作data—— 必须转成Uint8Array或Blob再发(例如await streamToBlob(compressedStream)) - .NET 的
GZipStream构造函数要求CompressionMode.Decompress,且传入的Stream必须可读(CanRead === true) - Node.js 的
zlib.createGunzip()若收到不完整流(如前端没controller.close()),会抛Z_DATA_ERROR
最易被忽略的是:前端用 pipeThrough 后没等 blob() 完成就发请求 —— 流式压缩是异步的,必须 await 完整 blob 或 arrayBuffer。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











