2015-09-03 39 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调用。 –

相关问题