Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/472.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Express中间件为所有app.get()和#x27;s_Javascript_Node.js_Express_Pug - Fatal编程技术网

Javascript Express中间件为所有app.get()和#x27;s

Javascript Express中间件为所有app.get()和#x27;s,javascript,node.js,express,pug,Javascript,Node.js,Express,Pug,我有一个Jade文件,我的所有模板都扩展了它,名为layout.Jade。在它中,如果用户当前已登录,我希望能够有一个注销按钮(这将跟踪In-req.session) 所以,jade会有这样的东西 -if (loggedin) a.navButton(href="/logout") Log Out app.get("/foo", function(req, res) { res.render("foo", {loggedin: req.session.isValidUser});

我有一个Jade文件,我的所有模板都扩展了它,名为layout.Jade。在它中,如果用户当前已登录,我希望能够有一个注销按钮(这将跟踪In-req.session)

所以,jade会有这样的东西

-if (loggedin)
  a.navButton(href="/logout") Log Out
app.get("/foo", function(req, res) {
    res.render("foo", {loggedin: req.session.isValidUser});
});
页面的路径类似于

-if (loggedin)
  a.navButton(href="/logout") Log Out
app.get("/foo", function(req, res) {
    res.render("foo", {loggedin: req.session.isValidUser});
});
问题是,我不想在每个路由中手动填充loggedin变量。是否有一种方法可以使用Express中间件为发送到res.render的对象自动设置一些默认选项?还是有更好的方法


基本上,我想问的是如何将一些变量集始终发送到模板,以及如何通过在路由中手动设置某些自定义变量,使它们在某些模板中可用。

在Express source中有一行代码对您非常有用:

// merge res.locals
options._locals = self.locals;
因此,当您运行
res.render()
时,Express还将获取存储在
res.locals
中的任何局部变量,并将它们传递到渲染中。因此,您只需将
res.locals.loggedin
设置为true,然后像往常一样运行
res.render()

app.get('/login', function(res, res) {
  res.locals.loggedin = true;
});
app.get('/foo', function(req, res) {
  res.render('foo', {});
});

如果按照六氰化物的建议,在
/login
路由中设置
res.locals.loggedin
,则该本地文件在
/foo
路由中不可用
res.locals
在每次请求时都被清除

您可以尝试将此路径置于其他路径之上:

app.all('*', function(req, res, next){
  if(req.user){
    res.locals.loggedin = true;
    res.locals.currentuser = req.user;
  };
  next();
});
非常确定,如果您在路由过程中修改req.user,您之前设置的
res.locals.currentuser
不会更新为新的
req.user
。但对此并不确定

实际上,我在呈现模板的每个页面上都使用了一个自定义的
render
函数,如下所示:

function myRender(templateName){
  return function(req, res){
    res.locals.currentuser = req.user || null;
    res.render(templateName);
  };
};
app.get('/foo'
, function(req, res, next){
  res.locals.bar = req.query['bar'] || "";
  console.log('passing request to myRender middleware');
  next();
}
, myRender('foo-jade-template')
)
我是这样用的:

function myRender(templateName){
  return function(req, res){
    res.locals.currentuser = req.user || null;
    res.render(templateName);
  };
};
app.get('/foo'
, function(req, res, next){
  res.locals.bar = req.query['bar'] || "";
  console.log('passing request to myRender middleware');
  next();
}
, myRender('foo-jade-template')
)

这样做的好处是,当我准备渲染某些内容时,而不是在执行路由之前,仅设置
res.locals.currentuser
。因此,如果我更改
req.user
,则保证在渲染时具有最新版本。

这似乎实际上是一个文档化的功能,我刚刚很难找到,除非有人有更好的方法;从最新的

应用程序局部变量:为所有模板提供应用程序局部变量 在应用程序中呈现。这对于提供帮助程序非常有用 功能到模板,以及应用程序级数据

所以在我的登录成功函数中

req.session.username = profile.username;
app.locals.username = profile.username;
我的注销功能

app.get('/logout', function (req, res) {
    delete app.locals.username;
    req.session.destroy();
    res.redirect('/login');
});
最后在layout.jade/我的所有模板中

- if(username)
  a.navButton(href="/logout") Logout

等等,Node.js不是在一个实例中为所有用户运行吗?我的意思是,
app.locals
不会为应用程序的每个用户引用同一个对象吗?
app.locals
对于特定于单个请求的数据肯定是错误的选择。如果试图对每个请求的数据使用
app.locals
,则有很多机会让数据在请求之间混合。这似乎是一个完全错误的答案,在多个用户加载的情况下会出现各种并发问题。关于您认为修改
req.user
无效的假设,为什么不呢?如果存储了引用,我不明白为什么。。。除非您执行
req.user=somethingElse稍后。对我来说,这个答案是最好的。res.locals是设置每个请求变量的正确方法,您可以在中间件中访问它。