调用 bodyParser.json() 后如何使用“express-http-proxy”?

hyp*_*oad 3 proxy node.js express meanjs

我正在构建一个跨系统管理应用程序,它将用作多个后端系统的管理工具。该应用程序建立在 Mean.js 之上。

我已经/proxy使用“express-http-proxy”设置了一个路由,将所有子路由发送到它们各自的后端系统端点。但是,在“express-http-proxy”可以继续之前,我需要在我的管理应用程序中对每个请求进行身份验证,然后使用目标后端系统凭据进行修饰。这是我的/proxy路线的一个例子......

app.use('/proxy', users.requiresLogin, expressHttpProxy(config.backendSystem.host, {
    forwardPath: function (req) {
        return '/1.0' + require('url').parse(req.url).path;
    },
    decorateRequest: function (req) {
        req.headers['content-type'] = 'application/json';
        req.headers['backend-system-id'] = config.backendSystem.id;
        req.headers['backend-system-key'] = config.backendSystem.key;
        return req;
    }
}));
Run Code Online (Sandbox Code Playgroud)

注意:
当前 backendSystem 凭据是根据我的管理应用程序运行的环境存储的。但是,将来 backendSystem 凭据将由用户指定,并且此/proxy路由将与当前显示的不同。

问题:
需要请求正文中的数据的代理路由不起作用。
例如POST /comments {"user": user_id, "text": "rabble rabble rabble"}

我发现了什么:
bodyParser.json()和“express-https-proxy”不太好。我已经通过bodyParser.json()express.js. 然而,这不是一个完整的解决方案,因为几乎所有的其他路线的需要bodyParser.json,例如/auth/signin

有没有人有一种干净的方法可以让我的路线例外,/proxy这样bodyParser.json就不会被调用?

Ark*_*ady 5

据我了解,问题的根源是这样的:

如果您是通过纯节点读取 POST 请求,则应该使用这样的代码

if (req.method == 'POST') {
    console.log("POST");
    var body = '';
    req.on('data', function (data) {
        body += data;
        console.log("Partial body: " + body);
    });
    req.on('end', function () {
        console.log("Body: " + body);
    });
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end('post received');
}
Run Code Online (Sandbox Code Playgroud)

换句话说,您需要使用 req.on('data') & req.on('end') 事件。但问题是,您只能使用此代码一次。在调用“结束”之后,请求被消耗。

那么你使用 bodyParser ,它会消耗请求,而代理与它无关。

实际上,在我看来,代理会等待 'data' 事件出现,但它会更新,因此代码会停止。

解决方案:

您需要“重新启用”这些事件。我使用了这段代码,它对我有用。

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

//call for proxy package
var devRest = require('dev-rest-proxy');

//init express (as default)
var users = require('./routes/users');
var app = express();
app.use(bodyParser.json());

//set the proxy listening port
app.set('port', 8080);

//process the POST request
app.post('/users/*', function(req, res) {

    //just print the body. do some logic with it
    console.log("req.body: ",req.body);

    //remove listeners set by bodyParser
    req.removeAllListeners('data');
    req.removeAllListeners('end');

    //add new listeners for the proxy to use
    process.nextTick(function () {
    if(req.body) {
       req.emit('data', JSON.stringify(req.body));
    }
    req.emit('end');
    });

    //forward the request to another server
    devRest.proxy(req,res, 'localhost', 3000);    

});

//start the proxy server
http.createServer(app).listen(app.get('port'), function(){
    console.log("Express server listening on port " + app.get('port'));
});

module.exports = app;
Run Code Online (Sandbox Code Playgroud)

schumacher-m帖子(nodejitsu 的 github)上找到的解决方案