我想实现这样的目标:
var c = require('connect');
var app = c();
app.use("/api", function(req, res, next){
console.log("request filter 1");
next();
});
app.use("/api", function(req, res, next){
console.log("request filter 2");
next();
});
app.use("/api", function(req, res, next){
console.log("request handler");
res.end("hello");
next();
});
app.use("/api", function(req, res, next){
console.log("response post processor");
next();
});
app.listen(3000);
当我 curl 的地址,我得到一个异常的控制台抱怨头不能被打扰后,被发送,这是公平的。只是我不碰回应对象。
/usr/bin/node app2.js
request filter 1
request filter 2
request handler
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:644:11)
at ServerResponse.res.setHeader (/home/zpace/node_modules/connect/lib/patch.js:59:22)
at next (/home/zpace/node_modules/connect/lib/proto.js:153:13)
at Object.handle (/home/zpace/WebstormProjects/untitled1/app2.js:25:5)
at next (/home/zpace/node_modules/connect/lib/proto.js:190:15)
at Object.handle (/home/zpace/WebstormProjects/untitled1/app2.js:19:5)
at next (/home/zpace/node_modules/connect/lib/proto.js:190:15)
at Object.handle (/home/zpace/WebstormProjects/untitled1/app2.js:14:5)
at next (/home/zpace/node_modules/connect/lib/proto.js:190:15)
at Function.app.handle (/home/zpace/node_modules/connect/lib/proto.js:198:3)
在调试NodeJS/Connect层时,我进入了一个部分,这意味着如果已经发送了头,那么执行路由处理程序必须初始化响应头。
问题是,如果上述行为是故意的(即在路由处理程序完成发送响应后执行任何代码是完全不可想象的,或者这只是连接中的一个错误?)
3条答案
按热度按时间sulc1iza1#
我不确定你是否找到了解决方案。
如果你想为请求周期设计一个后处理器,你可以使用一个中间件来监听响应对象上的“完成”事件。像这样:
附加到“finish”事件的函数将在响应被写出后执行(这意味着NodeJS已经将响应头部和主体移交给OS进行网络传输)。
我想这一定是你想要的。
vsaztqbk2#
我认为这是一个糟糕的规划问题。你应该用更好的方式解决这个问题。我不知道为什么你有一个请求处理程序和一个请求后处理程序分开,但让我们看看我们能做什么。
所以,是的,响应结束后,你不能再次阅读标题。
所以在调用后处理器之前不要完成响应。
这是一种解决方案,但这可能不是解决您的问题的最佳方法。
在我看来,在响应完成后调用
next()
真的很糟糕。如果你需要一个后处理器,为什么你在请求过滤器中这样做(或者这是什么)。调用函数但不调用next()
也许是这样:
或者这个:
next()
不是为那个用途,你用的。我希望我的回答对你有帮助,但我知道它不能涵盖一切,但你的回答也不是很具体。
bq9c1y663#
这是一个多么好的问题,可以在早上喝咖啡的时候试试!
因此,浏览
proto.js
,如果向下查看第102行app.handle
,它是中间件堆栈的处理程序代码,您将看到next()是如何操作的。在调用next()函数的地方,您可以看到它检查res.headerSent是否为true,如果是,则抛出错误。
如果将第14行修改为:
您将看到它实际上将“headersSent”设置为true。因此,在我们结束请求之后,您可以从next()代码中看到,由于所讨论的条件,它抛出了错误。