53

在升级到 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 );

澄清:

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

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 );
4

5 回答 5

106

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

IE:

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

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

    next();
});
于 2017-08-21T22:42:31.173 回答
60

关于 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 );

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

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

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

表达错误处理程序签名:

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

在中间件链中的最后一项上调用 next 是可选的,但如果你改变了事情,这可能是一个好主意。

于 2015-04-04T02:29:47.297 回答
4

您是否检查过将您的 console.log 放在 next() 调用之后?

express.use( function( req, res, next ) {
  next();
  console.log( "world" );
});
express.get( "/", function( req, res ) {
  res.send( "hello" );
});
于 2015-03-12T22:41:34.057 回答
0

您可以在不同的 js 文件中使用 Middle ware 函数,也可以使用 require 函数。以便在 http 请求之前和之后调用它。

    index.js:     
        const logger = require("./logger");    
           const express = require("express");    
           var app = express();    
           app.listen("3000",()=>console.log("listening on 3000..."))    
        app.use(logger("AppServer"));    
        //get expression    
        app.get("/", function(req,res){    
           console.log("res not received");    
            res.send("Hello World");    
           console.log("res received");    
        })   

    logger.js   

    module.exports = (applicationName) =>{
        return function log(req,res,next){
       console.log(applicationName+" started "+os.hostname);
        res.on("finish",()=>{
            console.log(applicationName+" completed "+os.hostname);
        })
        next();
        }};

output:   
AppServer started hostname-PC   
res not received   
res received   
AppServer completed hostname-PC 

注意:在 logger.js 中不要使用 res.on("finish",callback),你可以使用 req.on("end",callback)

于 2019-08-10T09:34:27.570 回答
0
const beforeMiddleware = function(req, res, next) {
  console.log('Before middleware triggered');
  next();
}

const responseHandler = function(req, res, next) {
    console.log('Response handler');
    res.status(200).send("Hello world");
    next();
}

const afterMiddleware = function(req, res, next) {
    console.log('After middleware triggered');
    next();
}

app.get('/', beforeMiddleware, handler, afterMiddleware);
于 2022-01-17T09:53:11.127 回答