json传输可压缩,需前后端协同:先 stringify 再用 lz-string 压缩为 utf-16 字符串,解压后 parse;注意校验、边界容错及适用场景,替代方案含 pako、gzip/brotli 和 messagepack。

JSON 本身是纯文本格式,不内置压缩能力,但可以在传输前对 JSON 字符串进行压缩,接收端再解压还原。关键在于:压缩的是 JSON 序列化后的字符串(即 JSON.stringify() 的结果),不是原始对象;解压后再用 JSON.parse() 解析。整个过程需前后端协同,且要注意编码、边界和浏览器兼容性。
选择轻量、兼容的压缩方案
浏览器环境推荐使用 lz-string(专为 JS 设计,支持 UTF-16,无依赖,体积小)。它提供基于 LZW 的压缩,比通用方案(如 pako + deflate)更简单,且能直接处理字符串,避免 base64 或二进制转换的额外步骤。
- 安装:
npm install lz-string,或通过 CDN 引入 - 压缩:
LZString.compressToUTF16(jsonStr)→ 返回紧凑的 UTF-16 字符串 - 解压:
LZString.decompressFromUTF16(compressed)→ 恢复原始 JSON 字符串 - 注意:不要用
compressToBase64,它会引入额外编码开销,且需额外处理 MIME 类型
在 fetch 请求中集成压缩逻辑
发送前压缩 JSON 字符串,设置自定义请求头标识压缩方式;响应时检查头信息,自动解压并解析。
- 发送示例: const data = { name: "Alice", tags: ["web", "js"] };
- 服务端收到后按相同规则解压(需对应实现),再 JSON.parse;返回时也可反向压缩
const jsonStr = JSON.stringify(data);
const compressed = LZString.compressToUTF16(jsonStr);
await fetch("/api/save", {
method: "POST",
headers: { "Content-Encoding": "lz-string-utf16" },
body: compressed
});
处理边界与容错
压缩/解压失败会导致 JSON 解析中断,必须加防护。
- 解压前校验输入有效性:
if (!compressed || typeof compressed !== 'string') throw new Error('Invalid compressed data'); - 解压后验证是否为合法 JSON:
try { JSON.parse(decompressed); } catch (e) { /* 降级为原始字符串或报错 */ } - 对空值、null、布尔等简单值,压缩收益极小,可跳过压缩逻辑
- 避免压缩已含大量重复字段的 JSON(如日志数组),效果有限;优先用于结构深、字符串多的场景(如富文本、配置快照)
替代方案与适用场景参考
若需更高压缩率或服务端主导流程,可考虑其他组合:
- pako + deflate:适合 Node.js 后端或 Web Worker 中处理大 JSON(压缩率优于 lz-string),但需处理 Uint8Array ↔ 字符串编码(如 TextEncoder/TextDecoder)
-
gzip / Brotli(由 HTTP 层处理):最省心——只需服务端开启响应压缩(如 Nginx 的
gzip on),浏览器自动解压;无需改 JS 代码,但无法控制单个请求是否启用 - MessagePack 或 CBOR:非 JSON 格式,二进制序列化,体积更小、解析更快;需前后端都支持,适合新架构或性能敏感场景
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











