Промежуточное ПО Node Express 4 после маршрутов

После обновления до Express 4 и удаления app.router я изо всех сил пытаюсь заставить промежуточное ПО запускаться после выполнения маршрутов.

например следующий код правильно отвечает «привет», но никогда не вызывает настроенное промежуточное ПО.

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

person goofballLogic    schedule 17.06.2014    source источник
comment
Работает для меня. Что у вас не работает.   -  person user568109    schedule 17.06.2014
comment
Я никогда не вижу вывода console.log   -  person goofballLogic    schedule 17.06.2014
comment
Показывается мне в командной строке node.js. У вас есть дополнительный код?   -  person user568109    schedule 17.06.2014
comment
Нет и все. Какой версией экспресса вы пользуетесь? (Я на 4.4)   -  person goofballLogic    schedule 17.06.2014
comment
У меня 4.4.3. Попытайся.   -  person user568109    schedule 17.06.2014
comment
Такой же, как у меня. Версия узла 0.11.10 в OS / X   -  person goofballLogic    schedule 17.06.2014
comment
Давайте продолжим это обсуждение в чате.   -  person goofballLogic    schedule 17.06.2014


Ответы (5)


Что касается Express 4, функция «после» из вашего второго примера никогда не вызывается, потому что средняя функция никогда не вызывает next ().

Если вы хотите, чтобы вызывалась функция «после», вам нужно добавить и вызвать следующий обратный вызов из вашей средней функции следующим образом:

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 проверяет количество аргументов в функции промежуточного программного обеспечения и выполняет другую логику. Возьмем, к примеру, экспресс-обработчики ошибок, для которых определены 4 параметра.

сигнатура экспресс-обработчика ошибок: app.use(function(err, req, res, next) {});

Вызов следующего для самого последнего элемента в вашей цепочке промежуточного программного обеспечения необязательно, но, вероятно, это хорошая идея, если вы когда-нибудь что-то измените.

person Joseph Snow    schedule 04.04.2015
comment
Вот это правда. В большинстве примеров маршруты экспресс-шоу указываются с арностью 2 в функции обработки. Но это исключает когда-либо добавление промежуточного программного обеспечения, которое должно выполняться после обработки маршрута. Для них это кажется странным условием. - person goofballLogic; 05.04.2015
comment
Я могу подтвердить, что это больше не работает - person Madeo; 10.02.2021

Правильный ответ - обратный вызов res.on("finish", cb).

i.e.:

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

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

    next();
});
person Test    schedule 21.08.2017
comment
этот парень говорит res.once, а не res.on lunchbadger.com/ - person datdinhquoc; 22.08.2018
comment
@datdinhquoc На самом деле это не имеет значения, поскольку res не будет доступен после того, как Express завершит работу с объектом ответа, поскольку каждый запрос вызывает создание новой пары req & res (Express). Вы правы и обычно то, что должен делать ответственный разработчик, но в данном конкретном случае они одинаковы. - person ozanmuyes; 15.05.2019
comment
@Catfish, здесь используются http функции модуля response узла документы узла. Как вы увидите в express docs, объект res в express представляет собой расширенную версию Собственный объект ответа Node и поддерживает все встроенные поля и методы. - person John Lee; 16.10.2019
comment
Этот метод хорош, когда люди уже создали API, не используя next во всех своих маршрутах. - person danthegoodman; 15.01.2021

Вы проверили, помещает ли ваш console.log после вызова next ()?

express.use( function( req, res, next ) {
  next();
  console.log( "world" );
});
express.get( "/", function( req, res ) {
  res.send( "hello" );
});
person marcosnils    schedule 12.03.2015
comment
Похоже на надежный вариант. - person Sergey; 15.01.2019
comment
Это не будет работать правильно, если запрос выполняет что-либо асинхронное. - person SystemParadox; 04.09.2019


вы можете использовать функцию Middleware в другом файле js, и вы можете использовать функцию 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)

person Loganathan .R    schedule 10.08.2019