express.js 4已经破坏了request.on('data')触发

时间:2017-03-20 00:06:17

标签: javascript node.js express

我希望有人可以找到我做错了什么,或者可以验证我发现的是真的。

在发送到node.js服务器的帖子上,世界上没有任何方式request.on('data')可行。 Body-parser / json只是没有正确设置表达,或者表达不是正常工作,或两者兼而有之。

以下是两个配对项目,一个服务器和一个服务器。一个客户端向服务器发送帖子。两者都在node.js.服务器包括express& body-parser

这是服务器端:

/* Used to start Node
var debug = require('debug')('ExpressApp1');
var app = require('../app');

app.set('port', process.env.PORT || 3000);

var server = app.listen(app.get('port'), function() {
    debug('Express server listening on port ' + server.address().port);
});
*/

var express = require('express');
var bodyParser = require('body-parser');
var app = express();

var fRawBody = function (req, res, buf, encoding) {
    if (buf && buf.length) {
        req.rawBody = buf.toString(encoding || 'utf8');
        console.log("buf", req.rawBody);
    }
}

app.use('/', bodyParser.json({ verify: fRawBody }));

app.use('/', function (req, res, next) {
    var data = '';
    req.on('data', function (chunk) {
        console.log("content-type", req.headers['content-type']);
        console.log('data: chunk', chunk);
        data += chunk;
    });
    req.on('end', function () {
        req.rawBody = data;
        console.log("raw", req.rawBody);
    });
    res.sendStatus(200);
});


module.exports = app;

--- app.js结束----

这是客户。

客户端response.on('data')运行正常。

var http = require("http");

var options = {
    "method": "POST",
    "hostname": "127.0.0.1",
    "port": "1337",
    "path": "/",
    "headers": {
        "content-type": "application/json",
        "cache-control": "no-cache",
        "postman-token": "44e8850a-7a9d-42ce-fbbf-02ac3e6e051b"
    }
};

var req = http.request(options, function (res) {
    var chunks = [];

    res.on("data", function (chunk) {
        chunks.push(chunk);
    });

    res.on("end", function () {
        var body = Buffer.concat(chunks);
        console.log(body.toString());
        process.exit();
    });
});

req.write(JSON.stringify({ data: { theGreatest: 'SMT' } }));
req.end();

我希望有人可以找到我做错了什么,或者可以验证我发现的是真的。

Node.js 4.2.4(客户端和服务器)

Express 4.9.8(服务器)

Body-Parser.js 1.8.4(服务器)

感谢。

2 个答案:

答案 0 :(得分:2)

我会接受我的评论并将其形成答案。

body-parser中间件将读取帖子的整个主体,解析它并将解析后的结果放入req.body。这意味着如果该中间件对于特定路由是活动的并且内容类型与中间件正在寻找的内容匹配,则它已经已经读取了流,并且当express到达您的路由处理程序时,没有更多的流要读取和因此你不会得到任何数据'事件

所以,如果你所追求的是作为字符串的原始未解析的身体,你有几个选择:

  1. 您可以从路径中删除正文解析器中间件,这样它就不会读取流,然后您可以在路由处理程序中自行读取流。这可以通过完全删除正文解析器中间件或以对您想要跳过它的特定路由无效的方式指定它来完成。

  2. 您可以使用bodyParser.text()代替bodyParser.json(),中间件会将正文作为文本读取,因此当快递调用您的路由处理程序时,正文已被读取为文本并放入{ {1}}为纯文本。

  3. 您使用已经解析的req.body而不是自己阅读和解析JSON。

答案 1 :(得分:0)

这是我能做到的最小化。这不使用Body-Parser。 由于Body-Parser完全取了'req'变量,所以混乱不堪。

谢谢&归功于jfriend00

- 等待帖子的服务器端 -

var express = require('express');
var app = express();
app.get('/', function (req, res) { res.sendStatus(200) });
app.post('/', function (req, res, next) {
    var data = '';
    req.on('data', function (chunk) {
        data += chunk;
    });
    req.on('end', function () {
        console.log("-----");
        console.log("hdr", req.headers['content-type']);
        console.log("raw", JSON.parse(data));
    });
    res.sendStatus(200);
});
module.exports = app;

- 客户端发送到服务器---

var http = require("http");
var options = {
    "method": "POST",
    "hostname": "127.0.0.1",
    "port": "1337",
    "path": "/",
    "headers": { "content-type": "application/json" }
};
var req = http.request(options, function (res) {
        process.exit();
});
req.write(JSON.stringify( { theGreatestHit: 'ChuckBerry Maybellene' }));
req.end();