2015-04-14 109 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())