ExpressJS 3.0 如何将 res.locals 传递给玉视图?

Posted

技术标签:

【中文标题】ExpressJS 3.0 如何将 res.locals 传递给玉视图?【英文标题】:ExpressJS 3.0 How to pass res.locals to a jade view? 【发布时间】:2012-09-15 00:42:30 【问题描述】:

我想在用户登录失败后显示一条消息,但我无法让变量显示在我的 Jade 视图中。

我有一些片段,我知道我必须在我的 app.configure() 中使用它:

    app.use (req, res, next) ->
      res.locals.session = req.session

我会设置用户 POST 错误密码后的 flash 信息:

     exports.postSession = (req, res) ->
       users = require '../DB/users'
       users.authenticate(req.body.login, req.body.password, (user) ->
       if(user)
         req.session.user = user
         res.redirect(req.body.redirect || '/')
       else
         req.session.flash = 'Authentication Failure!'
         res.render('sessions/new', title:'New', redirect: req.body.redirect )
      )

我不知道如何访问我的 Jade 文件中的 res.locals.session。我怀疑我是否设置正确。这个问题很像这个问题:Migrating Express.js 2 to 3, specifically app.dynamicHelpers() to app.locals.use? 但我仍然无法让它工作。如果有人可以向我展示一个在 res.local 中设置值并在视图中访问它们的简单示例,将不胜感激。

附言我确实知道 connect-flash,但我需要了解如何使内容在视图中可用。

这是我的应用程序:

app.configure(() -> 
  app.set('views', __dirname + '/views')
  app.set('view engine', 'jade')
  app.use(express.bodyParser())
  app.engine('.jade', require('jade').__express)
  app.use(express.methodOverride())
  app.use(express.cookieParser())
  app.use(express.session( store: new express.session.MemoryStore(reapInterval: 50000 * 10), secret: 'chubby bunny' ))
  app.use(express.static(__dirname + '/public'))
  app.use((req, res, next) ->
    res.locals.session = req.session
    next()
  )
  app.use(app.router)
)

【问题讨论】:

p.p.s 这方面的文档在哪里?我一直在看Migration guide、Express site 和Connect website,但我仍然无法弄清楚......也许只有我一个人,但我觉得我正在努力学习 ExpressJS,因为它的文档是如此稀疏。 你不能以session.flash访问它? 当我在 Jade 中执行此操作时:- if(session.flash) 它给了我一个错误,提示会话未定义.. 但是我如何在上面进行设置没有任何问题? 你的 app.use 是关于 app.router 还是 app[VERB]? app[VERB] 类似于 app.get app.post。这些都是 app.use(app.router) 中的所有路由,应该在任何其他 app.use 之后,除了任何错误处理程序。你把它们按什么顺序排列? 【参考方案1】:

只是给遇到相同问题的每个人做一个简短的总结,并认为更改res.redirect 已解决。

app.use 中间件放在之前 app.router 非常重要。请参阅 express 的作者 TJ Holowaychuck 的 cmets

https://groups.google.com/d/msg/express-js/72WPl2UKA2Q/dEndrRj6uhgJ

这是一个使用 express v3.0.0rc4 全新安装的示例

app.js:

app.use(function(req, res, next)
  res.locals.variable = "some content";
  next();
)

app.configure(function()
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
);

index.jade:

extends layout

block content
  h1= title
  p Welcome to #title
  p= variable

【讨论】:

是的,谢谢。忽略问题下方的 cmets,这是解决方法。 很高兴我能帮上忙!你要正式接受答案吗? 将 app.use 放在 app.router 在视图中正确传递本地值之前。【参考方案2】:

如果您使用的是 express.session(),您必须调用您的函数 AFTER express.session()BEFORE app .router,在 app.configure() 内部。

app.js

app = express();

app.configure(function()
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.session());

  // Give Views/Layouts direct access to session data.
  app.use(function(req, res, next)
    res.locals.session = req.session;
    next();
  );

  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
);

index.jade

extends layout

block content   
  h1= title   
  p My req.session.var_name is set to #session.var_name

【讨论】:

这是什么原因? 我目前是在express.session()之前使用的,为什么要避免呢?

以上是关于ExpressJS 3.0 如何将 res.locals 传递给玉视图?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 404 错误重定向到 ExpressJS 中的页面?

如何将 ExpressJS 服务器与 Angular2 集成

如何使用 nodejs 模块 http2 将 http2 与 ExpressJS 集成?

如何将用户凭据附加到 expressjs 中的请求管道?

如何将mongodb集合保存在数组中?在 expressJS 中使用猫鼬时?

带有 NuxtJS 中间件的 ExpressJS 将发布数据传递到页面