路由后的Node Express 4中间件

goo*_*gic 31 middleware node.js express express-4

在升级到Express 4并删除app.router后,我很难在路由执行后让中间件执行.

例如,以下代码正确响应"hello",但从不调用配置的中间件

var express = require( "express" )();

express.get( "/", function( req, res ) {

    res.send( "hello" );

} );
express.use( function( req, res, next ) {

    console.log( "world" );
    next();

} );

express.listen( 8888 );
Run Code Online (Sandbox Code Playgroud)

澄清:

以下代码在控制台上显示"之前",但不是"之后":

var express = require( "express" )();

express.use( function( req, res, next ) {

    console.log( "before" );
    next();

} );
express.get( "/", function( req, res ) {

    res.send( "hello" );

} );
express.use( function( req, res, next ) {

    console.log( "after" );
    next();

} );

express.listen( 8888 );
Run Code Online (Sandbox Code Playgroud)

小智 52

正确的答案是使用res.on("finish", cb)回调.

即:

express.use(function(req, res, next) {
    console.log("before");

    res.on("finish", function() {
        console.log("after");
    });

    next();
});
Run Code Online (Sandbox Code Playgroud)

  • 你能指出这方面的文件吗? (4认同)
  • 这家伙说“res.once”,而不是“res.on” https://www.lunchbadger.com/tracking-the-performance-of-express-js-routes-and-middleware/ (3认同)
  • 当人们已经创建了一个 API 而没有在所有路由中使用“next”时,此方法非常有用。 (3认同)
  • @datdinhquoc 这并不重要,因为在 Express 处理完响应对象后 `res` 将不可用,因为每个请求都会导致(通过 Express)创建一个新的 `req` 和 `res` 对。您是对的,通常是负责任的开发人员应该做的事情,但在这种特殊情况下,它们是相同的。 (2认同)

Jos*_*now 28

对于Express 4,第二个示例中的"after"函数永远不会被调用,因为中间函数从不调用next().

如果你想要调用"after"函数,那么你需要添加并调用中间函数的下一个回调,如下所示:

var express = require( "express" )();

express.use( function( req, res, next ) {

  console.log( "before" );
  next();

} );
express.get( "/", function( req, res, next ) {

  res.send( "hello" );
  next();      // <=== call next for following middleware 

} );
express.use( function( req, res, next ) {

  console.log( "after" );
  next();

} );

express.listen( 8888 );
Run Code Online (Sandbox Code Playgroud)

res.send() 将标头和响应写回客户端.

请注意,一旦调用了res.send(),您就不会想要更新响应头或内容.但您可以执行其他任务,如数据库更新或日志记录.

请注意,express查看中间件函数中的参数数量并执行不同的逻辑.以快速错误处理程序为例,它定义了4个参数.

表达错误处理程序签名 app.use(function(err, req, res, next) {});

在中间件链的最后一个项目上调用next是可选的,但如果你改变了一些东西,可能是一个好主意.