2015-04-14 107 views
9

我也发布了这个to the relevant issue on http-proxy当使用http-proxy和body-parser与express时,节点挂起POST请求

我使用http-proxyexpress,所以我可以拦截我的客户端和api之间的请求,以添加一些用于身份验证的cookie。

为了验证客户端必须以x-www-form-urlencoded作为内容类型发送POST请求。所以我使用body-parser中间件来解析请求体,以便我可以在请求中插入数据。

http-proxy使用body-parser时出现问题据推测,因为它将流体解析为流并且从不关闭它,因此代理永远不会完成请求。

There is a solution in the http-proxy examples在请求解析完成后“重新流”请求,我尝试使用它。我也试图使用connect-restreamer solution in the same issue没有运气。

我的代码看起来像这样

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

var proxy = httpProxy.createProxyServer({changeOrigin: true}); 
var restreamer = function(){ 
    return function (req, res, next) { //restreame 
    req.removeAllListeners('data') 
    req.removeAllListeners('end') 
    next() 
    process.nextTick(function() { 
     if(req.body) { 
     req.emit('data', req.body) //error gets thrown here 
     } 
     req.emit('end') 
    }) 
    } 
} 

var app = express(); 

app.use(bodyParser.urlencoded({extended: false, type: 'application/x-www-form-urlencoded'})); 
app.use(restreamer()); 

app.all("/api/*", function(req, res) { 
    //modifying req.body here 
    // 
    proxy.web(req, res, { target: 'http://urlToServer'}); 
}); 

app.listen(8080); 

,我收到此错误

/Code/project/node_modules/http-proxy/lib/http-proxy/index.js:119 
throw err; 
    ^
Error: write after end 
    at ClientRequest.OutgoingMessage.write (_http_outgoing.js:413:15) 
    at IncomingMessage.ondata (_stream_readable.js:540:20) 
    at IncomingMessage.emit (events.js:107:17) 
    at /Code/project/lib/server.js:46:25 
    at process._tickCallback (node.js:355:11) 

我试图调试流,但我抓住了救命稻草。请提供任何建议?

+0

只是想知道你为什么不直接使用明确的中间件,而不是HTTP代理?您可以拦截/修改所有使用中间件的请求。 – jfriend00

回答

-1

http-proxy在处理POST正文时尤其糟糕,特别是在最新版本的Node中;中间件攻击并不总是适用于所有的POST请求。我建议你使用像NGINX或HAPROXY这样的专用http代理引擎,那些工作最好。

2

我遇到这个问题,我无法得到restreaming工作。我的解决方案虽然简单,但可能不适合您的项目。

我最终将body-parser中间件移动到了路由本身,而不是路由中间件,因为我的项目只有几条路由并且重置通过了我的http代理中间件。

因此,不是这样的:

router.use(bodyParser.json()); 

router.get('/', function(){...}); 

router.use(httpProxy()); 

我这样做:

router.get('/', bodyParser.json(), function(){...}) 

router.use(httpProxy())