express.js中的第二个路由器或中间件路径

时间:2013-07-17 09:19:33

标签: node.js express

我的应用程序通常有中间件堆栈:

  app.configure(function() {
    app.use(express.static(PUBLIC_DIR));
    app.use(express.favicon());
    app.use(express.bodyParser({
      keepExtensions: true,
      uploadDir: '/tmp/neighr'
    }));
    app.use(express.methodOverride());
    app.use(express.cookieParser());
    app.use(express.session({
      secret: '***REDACTED***',
      store: sessionStore,
    }));
    app.use(express.csrf());
    app.use((require('connect-flash'))());
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(function(req, res, next) {
      app.locals({
        _csrf: req.session._csrf,
        url: req.url,
        user: req.user,
        authenticated: req.isAuthenticated(),
        messages: {
          info: req.flash('info'),
          error: req.flash('error'),
          success: req.flash('success')
        }
      });
      next();
    });
    app.use(app.router);
    app.use(express.logger());
    app.use(express.errorHandler());
  });

正如您所看到的,express.static是堆栈中的第一个,因此静态资源将在不经过整个会话的情况下提供,只会使加载时间更长。

但是,我确实有一些动态数据,我希望在没有会话的情况下提供服务:

app.get('/avatar/:id', function(req, res) {
  var fid = res.params.id;
  /* load binary from database */
  res.send(data);
});

此路由位于堆栈末尾的app.router内。我想继续声明这个和其他路由,但是如何在会话中间件之前使用express来解析这些?

将来可能会有更多这样的动态路线,参数更多。

1 个答案:

答案 0 :(得分:6)

一旦声明了路由,Express会在此时将router中间件插入中间件堆栈,因此如果您在加载会话中间件之前声明单个路由,所有路由请求会跳过会话中间件:

app.get('/one', ...); // inserts `app.router` into the stack at this point
app.use(express.session(...));
app.get('/two', ...); // will skip the session middleware

我能想到两个解决方案:创建自己的中间件来处理不应该通过会话中间件传递的请求,或者为要通过它运行的每个路由显式设置会话中间件。

第一个解决方案:

app.use(function(req, res, next) {
  if (req.path.indexOf('/avatar/') === 0) {
    // parse out the `id` and return a response
  }
  next();
});

这显然不是很灵活。

第二个解决方案:

// instantiate the session middleware:
var sessionMiddleware = express.session(...);

// default setup: insert the router before the session middleware:
app.use(app.router);
app.use(sessionMiddleware);

// Pass it explicitly to the route:
app.get('/two', sessionMiddleware, function(req, res) {
  ...
});

在您使用Passport的情况下,您可能需要一组中间件:

var authMiddleware = [
  express.session(...),
  passport.initialize(),
  passport.session()
];
app.get('/two', authMiddleware, ...);

看看Express是如何实现的,我认为不可能实例化第二个路由器(并使其正常运行)。