1

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

  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堆栈的末尾。我想保留声明此路由和其他路由的方式,但是如何在会话中间件之前快速解析这些路由?

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

4

1 回答 1

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 是如何实现的,我认为不可能实例化第二个路由器(并让它正常工作)。

于 2013-07-17T10:56:40.010 回答