有条件地使用中间件取决于请求参数表达

Mic*_*ael 32 node.js express

我试图根据请求查询参数决定使用中间件.

在主模块中,我有这样的事情:

app.use(function(req, res){
  if (req.query.something) {
    // pass req, res to middleware_a
  } else {
    // pass req, res to middleware_b
  }
});
Run Code Online (Sandbox Code Playgroud)

middleware_a并且middleware_b都是由函数创建的快速应用程序,express()而不是常规中间件函数(function(req, res, next))

找不到办法做到这一点

pir*_*lot 28

连接/表达'中间件'没有什么神奇之处:它们只是函数 - 你可以像调用任何其他函数一样调用它们.

所以在你的例子中:

app.use(function(req, res, next){
  if (req.query.something) {
    middlewareA(req, res, next);
  } else {
    middlewareB(req, res, next);
  }
});
Run Code Online (Sandbox Code Playgroud)

也就是说,可能有更优雅的方式来构建分层表达应用程序.查看TJ的视频


Chr*_*ian 8

我知道这个问题已经过时了,但我想分享一下我的解决方案.我通过创建一个返回带有回调的中间件的函数来解决这个问题.

示例中间件:

function isAdminUser(callback){
    return function(req, res, next){
        var userId = callback(req);
        // do something with the userID
        next();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在快速路由器对象中执行以下操作

app.use(isAdminUser(function(res){
    return res.body.userId
    });
Run Code Online (Sandbox Code Playgroud)


cyb*_*bat 6

我不会使用该中间件 - 而是在中间件A和B中检查以下内容:

//Middleware A
app.use(function(req, res){

  // If it doesn't match our condition then send to next middleware
  if (!req.query.something) {
    next();
  } else {
    // We're good - let this middleware do it's thing
    ...
    next();
   }
});
Run Code Online (Sandbox Code Playgroud)

与中间件B相同

//Middleware B
app.use(function(req, res){

  if (req.query.something) {
    ...
});
Run Code Online (Sandbox Code Playgroud)


Obe*_*ano 6

如果您像我一样希望在条件中间件(例如通行证或会话)下使用第三方中间件,那么您可以这样做:

app.use((req, res, next) => {
    // your condition
    if (req.url !== 'no-session') {
      // Your middleware
      session()(req, res, next);
    } else {
      next();
    }
  })
Run Code Online (Sandbox Code Playgroud)

仅当满足条件时才会触发会话。您必须将 (req, res, next) 作为参数发送给第二个函数,该函数始终返回以连接中间件。这应该适用于任何中间件,无论是您自己的还是第三方的。