【问题标题】:Unzip POST body with node + express使用 node + express 解压 POST 正文
【发布时间】:2013-01-07 11:20:01
【问题描述】:

我有一个简单的节点应用程序,应该从客户端写入指标。 客户端以使用 python 的 zlib 模块压缩的 json 格式发送指标,我正在尝试添加一个中间件以在快速 bodyParse 发生之前解压缩请求帖子。

我的中间件就是 express 默认提供的:

app.configure(function(){
    app.set('port', process.env.PORT || 3000);
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade');
    app.use(express.favicon());
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser('your secret here'));
    app.use(express.session());
    app.use(app.router);
    app.use(require('less-middleware')({ src: __dirname + '/public' }));
    app.use(express.static(path.join(__dirname, 'public')));
});

我尝试添加一个简单的中间件来获取数据然后解压缩:

app.use(function(req, res, next) {
    var data = '';
    req.addListener("data", function(chunk) {
        data += chunk;
    });

    req.addListener("end", function() {
        zlib.inflate(data, function(err, buffer) {
            if (!err) {
                req.body = buffer;
                next();
            } else {
                next(err);
            }
        });
    });
});

问题在于 zlib.inflate 我收到此错误:

Error: incorrect header check

数据已经用python的zlib模块压缩了:

zlib.compress(jsonString)

但似乎 unzip、inflate、gunzip 都不起作用。

【问题讨论】:

  • 你确定你没有从 zlib.unzip 得到一个“错误”,因此没有调用 next() 吗?如果是这种情况,请尝试将数据切换为数组。看看这个答案stackoverflow.com/a/12776856/30763另外确保你的中间件在bodyParser之前使用。
  • 该答案不是用于解压缩节点而不是客户端完成的请求吗?
  • @alex88 在任何情况下,如果出现错误,您应该致电next(err)。我还建议你放弃bodyParser 中间件,直接使用req.body = JSON.parse(buffer)
  • 好的,问题出在解压缩功能上,谢谢指出,我现在已经更正了这个问题。

标签: node.js express zlib


【解决方案1】:

自己找到了解决办法,问题出在这段代码上:

req.addListener("data", function(chunk) {
    data += chunk;
});

似乎连接请求数据不正确,因此我已将中间件切换为:

app.use(function(req, res, next) {
    var data = [];
    req.addListener("data", function(chunk) {
        data.push(new Buffer(chunk));
    });
    req.addListener("end", function() {
        buffer = Buffer.concat(data);
        zlib.inflate(buffer, function(err, result) {
            if (!err) {
                req.body = result.toString();
                next();
            } else {
                next(err);
            }
        });
    });
});

连接缓冲区完美运行,我现在可以解压缩请求正文。

【讨论】:

  • 如果您想知道为什么,那是因为您的第一次尝试是将原始二进制数据转换为字符串。由于 UTF-8 并不意味着保存任意字节(就像您在压缩数据流中找到的字节),因此您的数据已损坏。默认情况下,data 事件会为您提供Buffer,这是 Node 处理原始数据的方式。
  • @josh3736 并转换为字符串丢失了一些数据?所以块已经是一个缓冲区,我可以轻松地推送它而不是创建一个新的缓冲区?
  • Yes. From the docs for the data event: "如果编码设置为request.setEncoding(),则chunk 为字符串,否则为Buffer"
  • 嘿,你能发布完整的应用程序初始化代码吗?我遇到了一个问题,即 inflate 的回调(我正在使用 gunzip)我的结果是空的
【解决方案2】:

我知道这是一个很晚的响应,但是使用模块 body-parser,它会:

返回只解析 json 的中间件。此解析器接受正文的任何​​ Unicode 编码,并支持 gzip 和 deflate 编码的自动膨胀。

var bodyParser = require('body-parser');
app.use( bodyParser.json() );       // to support JSON-encoded bodies

【讨论】:

    猜你喜欢
    • 2017-11-17
    • 1970-01-01
    • 2012-05-12
    • 1970-01-01
    • 2019-01-10
    • 2015-07-04
    • 2017-02-22
    • 1970-01-01
    • 2014-05-10
    相关资源
    最近更新 更多