exit from chain of route specific middleware in express/ nodejs

前端 未结 3 1414
清歌不尽
清歌不尽 2021-02-08 05:07

I have a chain of \"route specific middleware\" for this route, like so:

    var express = require(\'express\');
    var server = express();
    var mw1 = functi         


        
相关标签:
3条回答
  • 2021-02-08 05:54

    A little more tinkering yielded the answer:

    var express = require('express');
    var server = express();
    var mw1 = function(req, resp, next) {
      //do stuff
      if (success) {
        next();
      } else {
        resp.send(406, 'Invalid because of this');
        req.connection.destroy(); //without calling next()
      }
    };
    var mw2 = function(req, resp, next) {
      //do stuff
      if (success) {
        next();
      } else {
        resp.send(406, 'Invalid because of that');
        req.connection.destroy(); //without calling next()
      }
    };
    server.post('/some/path', [mw1, mw2], function(req, resp) {
      //write response
    });
    

    The trick was send a response: resp.send(406, 'Invalid because of this');

    Just prior to destroying the connection: req.connection.destroy();

    In fact not destroying the connection, I found to also work, in the general case.

    (But was required in my specific case, and is out of the scope of this question.)

    If the response has already been sent, then express does not automatically call next() for you, as it appeared to do otherwise.

    0 讨论(0)
  • 2021-02-08 05:58

    You can call next( 'route' ), as said on the express api reference, application routing section:

    Multiple callbacks may be given, all are treated equally, and behave just like middleware, with the one exception that these callbacks may invoke next('route') to bypass the remaining route callback(s).

    Example

    var express = require('express')
      , app = express()
    ;
    
    // keep an eye on the function names
    app.post( '/some/path', middleware1, middleware2, function route1( req, res, next ) {
          // write response
    });
    app.all( '*', function route2( req, res, next ) {
        // do something like handle a 404 request
    });
    app.use(function errorHandler( err, req, res, next ) {
        // handle error
    });
    
    function middleware1( req, res, next ) {
        // ...
        if ( !success ) {
            // bypasses middleware2 and route1, route2 will be called
            return next( 'route' );
        }
        // calls middleware2
        next();
    }
    // intentionally similar to middleware1 to keep things clear
    function middleware2( req, res, next ) {
        if ( !success ) {
          // bypasses route1 and route2
          // errorHandler will be called with the error
          return next( Error( 'middleware 2 failed' ) );
        }
        // calls route1
        next();
    }
    
    0 讨论(0)
  • 2021-02-08 06:10

    I was under the impression that if you neither call next() nor send a response in a route handling function, express just hangs. Also FWIW I haven't used an array, mine looks like server.post('/some/path', mw1, mw2, function(req, resp) {...

    Anyway. One alternative might be to restructure your code so you only have a single handling function. Do you have a good reason for mw1 and mw2 being middleware instead of regular async functions your handler calls?

    var express = require('express');
    var server = express();
    
    var mw1 = function(req, res, callback) {
      // do stuff with req/res if necessary but don't send a response
      if (success) {
        callback(null);
      } else {
        callback('Error');
      }
    };
    
    var mw2 = function(req, res, callback) {
      //do other stuff but don't send a response
      if (success) {
        callback(null);
      } else {
        callback('Error');
      }
    };
    
    function mwBoth(req, res){
      mw1(req, res, function(err){
        if(err){ return res.send(500) };
        mw2(req, res, function(err){
          if(err){ return res.send(500) };
          // neither had an error
          res.redirect('/some/other/path');
        });
      });
    };
    
    server.post('/some/path', mwBoth);
    
    0 讨论(0)
提交回复
热议问题