监控数据传输时gzip压缩失效怎么办?

シ恩硕 阅读 32

我在用fetch发送POST请求压缩监控数据时,明明设置了gzip压缩,但后端收到的还是明文数据。我用compressor-gzip库压缩了JSON字符串,代码也设置了Content-Encoding: gzip头,但后端返回400说数据损坏了。这是哪里出问题了?

尝试过把压缩后的ArrayBuffer转成base64再发,但这样反而增大了数据量。下面是核心代码片段,大家帮忙看看参数有没有设置错:


import { gzip } from 'compressor-gzip';

const data = { metrics: [...] };
const compressed = gzip(JSON.stringify(data));
fetch('/api/log', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Encoding': 'gzip'
  },
  body: Buffer.from(compressed).toString('base64') // 这里是否该直接用ArrayBuffer?
});

后端Node.js服务用express处理时,req.body一直是空对象,用Postman模拟请求却能正常接收…

我来解答 赞 6 收藏
二维码
手机扫码查看
1 条解答
常青 Dev
问题出在好几个地方,直接给你指出来并优化一下代码。

1. Content-Type 不应该是 application/json,因为已经是压缩数据了,不是纯JSON字符串。
2. 你把压缩后的数据转成Base64再发,这完全是反人类操作。Base64会增加约33%的数据量,完全违背了压缩的初衷。
3. 后端Express默认是没法处理gzip压缩数据的,你需要用中间件比如 body-parser-raw 来解析原始二进制数据。

下面是修正后的前端代码:
import { gzip } from 'compressor-gzip';

const data = { metrics: [...] };
const compressed = gzip(JSON.stringify(data));
fetch('/api/log', {
method: 'POST',
headers: {
'Content-Encoding': 'gzip',
'Content-Type': 'application/octet-stream' // 设置为二进制流
},
body: compressed.buffer // 直接发送ArrayBuffer
});


后端部分要用 body-parser-raw 来解析原始数据,示例:
const express = require('express');
const zlib = require('zlib');
const bodyParser = require('body-parser');
const app = express();

app.use(bodyParser.raw({ type: '*/*', limit: '50mb' }));

app.post('/api/log', (req, res) => {
if (req.headers['content-encoding'] === 'gzip') {
zlib.unzip(req.body, (err, buffer) => {
if (err) return res.status(400).send('解压失败');
const jsonData = JSON.parse(buffer.toString());
console.log(jsonData);
res.send('成功');
});
} else {
res.status(400).send('缺少gzip编码');
}
});

app.listen(3000);


这样改完就效率更高了,不会再有数据损坏的问题。记得不要再用Base64这种低效的东西了,真没必要。
点赞 7
2026-02-01 08:00