2015-09-03 37 views
1

我正在編寫Express.js應用程序,它應該將請求路由到某個代理服務器,作爲管道中的最後一步。我使用http-proxy代理庫,因爲它支持websockets。問題是我需要在重定向請求後繼續使用我的應用程序,以便收集一些我將用於記錄的信息(響應時間,api調用等)。這個想法是在請求被代理之後調用next()函數,它應該將我返回到堆棧中的第一個中間件?(請糾正我,如果我錯了),然後計算起始點和當前中間件之間的時間差。Node.js Express - 在代理請求後調用next()

調用proxy.web(req, res, {target: serviceAddress});next()之後它之後 - 我得到的錯誤:

_http_outgoing.js:335 
 
    throw new Error('Can\'t set headers after they are sent.'); 
 
     ^
 
Error: Can't set headers after they are sent. 
 
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11) 
 
    at d:\WebStorm Projects\api-gateway\node_modules\http-proxy\lib\http-proxy\passes\web-outgoing.js:85:11 
 
    at Array.forEach (native) 
 
    at Array.writeHeaders (d:\WebStorm Projects\api-gateway\node_modules\http-proxy\lib\http-proxy\passes\web-outgoing.js:84:35) 
 
    at ClientRequest.<anonymous> (d:\WebStorm Projects\api-gateway\node_modules\http-proxy\lib\http-proxy\passes\web-incoming.js:149:20) 
 
    at ClientRequest.emit (events.js:107:17) 
 
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:426:21) 
 
    at HTTPParser.parserOnHeadersComplete (_http_common.js:111:23) 
 
    at Socket.socketOnData (_http_client.js:317:20) 
 
    at Socket.emit (events.js:107:17)

是否有保持proxy.web(...)工作後的溶液,叫什麼名字?或者如果我的方法是錯誤的,任何人都可以爲我提供一個解決方案嗎?

+0

我還沒有使用這個代理模塊。這聽起來像是當請求被代理時,它結束請求並且響應現在被傳送/發送回客戶端。 –

回答

2

你不應該在發送迴應之後調用next(),因爲你主動不希望剩下的中間件(它也會嘗試發送響應)運行。

相反,你應該把所有的日誌記錄中間件放在第一位。

+0

謝謝澄清。但是在那種情況下,計算所有中間件所用時間的方法是什麼?我的想法是將我的計算中間件作爲堆棧中的第一個,然後創建'new Date()'對象並調用'next()' - 繼續所有中間件並最終代理我認爲要調用的請求next )',這應該使我回到第一個中間件,在那裏我可以創建第二個'Date()'對象並計算差異。 –

+0

@OstapLisovyj:這實際上不起作用,因爲大多數服務中間件都是異步的。執行此操作的典型方法AFAIK是代理'res.end()'來查看響應何時發送。 – SLaks

+0

對不起,我在這裏有點困惑,應該像'proxy.web(req,res.end(),{target:serviceAddress});'?未來的要求是使用所有相關信息記錄每個API調用,並根據該信息對某個端點執行其他API調用。 –

相關問題