如何在NodeJS Express应用程序中使用MongoDB存储网站配置?

6

我有一个运行在NodeJS 0.8.8上,使用MongoDB和Jade模板语言的Expressjs应用程序,并且我想允许用户配置许多站点宽度的展示选项,例如页面标题、标志图像等。

我该如何将这些配置选项存储在MongoDB数据库中,以便在应用程序启动时读取它们,在应用程序运行时对其进行操作,并在jade模板中显示它们?

以下是我的一般应用程序设置:

var app = module.exports = express();
global.app = app;
var DB = require('./accessDB');
var conn = 'mongodb://localhost/dbname';
var db;

// App Config
app.configure(function(){
   ...
});

db = new DB.startup(conn);

//env specific config
app.configure('development', function(){
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
}); // etc

// use date manipulation tool moment
app.locals.moment = moment;

// Load the router
require('./routes')(app);

到目前为止,我已经为“siteConfig”集合创建了一个名为“Site”的模型,并在accessDB.js中编写了一个名为getSiteConfig的函数,该函数运行Site.find()...以检索集合中一个文档中的字段。

那么这就是问题的关键:我应该如何将这些字段注入到express应用程序中,以便它们可以在整个站点中使用?我应该像使用moment.js工具一样遵循相同的模式吗?像这样:

db.getSiteConfig(function(err, siteConfig){
  if (err) {throw err;}
  app.locals.siteConfig = siteConfig;
});

如果不行,那正确的做法是什么呢?
谢谢!

这是您想要存储在会话中的内容吗? - c0deNinja
不,我不这么认为。我不希望客户端能够访问它。我只想让服务器端的Express应用程序(特别是Jade)能够访问它。我已经让它在console.log的点上工作了。我想我应该尝试将其添加到app.locals中,看看会发生什么,但我不确定使用它的安全性(或稳定性)。 - tutley
1个回答

26

考虑使用 express 中间件来加载网站配置。

app.configure(function() {
  app.use(function(req, res, next) {
    // feel free to use req to store any user-specific data
    return db.getSiteConfig(req.user, function(err, siteConfig) {
      if (err) return next(err);
      res.local('siteConfig', siteConfig);
      return next();
    });
  });
  ...
});
抛出错误会导致应用崩溃,因此最好不要这样做。而是使用next(err); 将错误传递给 express 的errorHandler

如果您已经在之前的中间件中验证了用户并将其数据存储在 req.user 中,那么您可以使用它来从数据库获取正确的配置。

但是,在 express 中间件中使用getSiteConfig 函数时要小心,因为它会暂停 express 进一步处理请求直到收到数据。

您应该考虑将 siteConfig 缓存到 express 会话中以加速应用程序。在 express 会话中存储特定于会话的数据绝对安全,因为用户无法访问它。

以下代码演示了在 express 会话中缓存 siteConfig 的想法:

app.configure(function() {
  app.use(express.session({
    secret: "your sercret"
  }));
  app.use(/* Some middleware that handles authentication */);
  app.use(function(req, res, next) {
    if (req.session.siteConfig) {
      res.local('siteConfig', req.session.siteConfig);
      return next();
    }
    return db.getSiteConfig(req.user, function(err, siteConfig) {
      if (err) return next(err);
      req.session.siteConfig = siteConfig;
      res.local('siteConfig', siteConfig);
      return next();
    });
  });
  ...
});

1
这是一个很棒的答案,我非常感激。不幸的是,我不能投票支持它,因为我没有足够的声望,但如果有人正在关注,请投票支持它。再次感谢。 - tutley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接