从express/nodejs中的路由链特定中间件退出

bgu*_*uiz 10 javascript middleware connect node.js express

我为这条路线设置了一系列"路由特定的中间件",如下所示:

    var express = require('express');
    var server = express();
    var mw1 = function(req, resp, next) {
        //do stuff
        if (success) {
            next();
        } else {
            req.connection.destroy(); //without calling next()
        }
    };
    var mw2 = function(req, resp, next) {
        //do stuff
        if (success) {
            next();
        } else {
            req.connection.destroy(); //without calling next()
        }
    };
    server.post('/some/path', [mw1, mw2], function(req, resp) {
        //write response
    });
Run Code Online (Sandbox Code Playgroud)

[mw1, mw2]是特定于路由的中间件/some/path.

这与服务器范围的中间件不同,如下所示:

    server.use(mw1);
    server.use(mw2);
Run Code Online (Sandbox Code Playgroud)

它适用于所有定义的路线.

现在我的问题是我想退出链.即如果success是假的mw1,我不希望mw2被召唤.如果success是假的mw2,我不会没有调用路由功能.目前,双方mw1mw2似乎得到所谓的是否next()叫-我不知道为什么.

我该怎么做呢?

lac*_*ass 18

你可以打电话next( 'route' ),如快递api参考文章application routing所述:

可以给出多个回调,所有回调都是相同的,并且行为就像中间件一样,但有一个例外,即这些回调可能会调用next('route')以绕过剩余的路由回调.

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();
}
Run Code Online (Sandbox Code Playgroud)


bgu*_*uiz 4

稍微修改一下就得到了答案:

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
});
Run Code Online (Sandbox Code Playgroud)

诀窍是发送响应:resp.send(406, 'Invalid because of this');

就在破坏连接之前:req.connection.destroy();

事实上,在一般情况下,我发现在不破坏连接的情况下也可以工作。

(但在我的具体情况下是必需的,并且超出了这个问题的范围。)

如果回复已发送,则 Express 不会自动呼叫next()您,否则看起来会这样做。