我的Node.js服务器需要在POST请求中接收大量压缩的JSON(gzip)数据。我已经为gunzip
POST的有效负载添加了一些代码,但结果总是不正确的,具体取决于发布的JSON的大小。
var http = require('http');
var zlib = require('zlib');
var port = process.env.port || 1337;
http.createServer(function(req, res) {
if (req.method == 'POST') {
if( req.headers['content-encoding'] == 'gzip' ) {
var body = [];
req.on('data', function (data) {
console.log('Receiving data...');
body.push(data);
});
req.on('end', function () {
console.log('Data received! Uncompressing...');
var buffer = Buffer.concat(body);
zlib.gunzip(buffer, function(err, result) {
if (!err) {
console.log('Unzipped!!')
var r = result.toString();
console.log(r)
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(r);
} else {
console.log(err);
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('Something went wrong!');
}
});
});
}
else {
console.log('Everything OK with uncompressed requests!');
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Some JSON was received!\n');
}
req.on('error', function(err){
console.log(err);
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('Something went wrong!');
});
}
else {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n');
}
}).listen(1337);
如果我发送正常的,未压缩的JSON数据,一切正常。
压缩的结果:
正如评论中所指出的,这不是不正确的行为,因为有效负载是如此之小以至于没有压缩。{"id":1, "name":"Gabe"}
- >返回500,错误:不正确的标题检查]错误:-3,代码:'Z_DATA_ERROR',当试图解压缩数据时。
{"id":1,"name":"Gabe","age":33,"address":"555 Road, City, Province","occupation":"I exchange code for money"}
- >请求在request.on('data'...
之后突然以504结束,尽管该过程继续并显示正确的未压缩数据,如下所示。
{"id":1,"name":"Gabe","age":666,"address":"666 Road, City, Province","occupation":"I sleep during the day and write code at night... not"}
- >它一直在接收数据而不再做任何事情。
为了测试,我已经将Fiddler配置为在使用Rules -> Customize Rules设置Content-Encoding标头时发送压缩数据:
if (oSession.requestBodyBytes != null && oSession.requestBodyBytes.Length>50 && oSession.oRequest.headers.Exists("Content-Encoding")){
oSession.requestBodyBytes = Utilities.GzipCompress(oSession.requestBodyBytes);
oSession["Content-Length"] = oSession.requestBodyBytes.Length.ToString();
oSession["Content-Encoding"] = "gzip";
}
示例请求:
POST http://localhost:1337/ HTTP/1.1
User-Agent: Fiddler
Content-Encoding: gzip
Host: localhost:1337
{"id":1,"name":"Gabe","age":00,"address":"555 Road, City, Province","occupation":"I exchange code for money"}
我尝试听错并使用域名,但我没有看到任何错误产生。我也尝试使用Express手动操作并使用支持GZIP和Deflate的body-parser模块,行为是相同的。使用节点0.10.18和0.10.30进行测试,不使用Express,最后使用Express 3和4进行测试。
那么,这里发生了什么?我是如此盲目以至于我在某个地方错过了一个冒号吗?这是Node中的一个错误吗?这是我向Fiddler发送请求的方式吗?