Nodejs中关于res.locals的问题

Nodejs中关于res.locals的问题

以下这两种将元素传递给前台的方式有什么区别吗?我试验了效果一样

app.get('/', function(req,res){
        res.locals.test="test";//???
        res.render('index',{
            title:'主页',
            user: req.session.user,
            posts:posts,
            success:req.flash('success').toString()
        });
});


app.get('/', function(req,res){
    res.render('index',{
        title:'主页',
        user: req.session.user,
        posts:posts,
        test:"testData",//???
        success:req.flash('success').toString()
    });
});

都能在ejs通过<%=locals.testData%>或<%=test%>获取数据,那上面的两种写法有什么区别吗?

在微博的那个示例中,直接将res.locals写在了app.js中,那这个locals是针对哪个请求呢呢?难道是全局请求?那岂不是和app.locals一样了?

app.use(function(req,res,next){
var err = req.flash('error'),
    success = req.flash('success');
res.locals.user = req.session.user;
res.locals.error = err.length ? err : null;
res.locals.success = success.length ? success : null;
next();
});

求指点


8 回复

在Node.js中,res.locals是一个对象,用于向模板传递数据。它在每个请求中都是独立的,并且可以覆盖。下面是关于你提出的问题的一些详细解释和示例。

示例代码

const express = require('express');
const app = express();

app.set('view engine', 'ejs');

app.get('/', function (req, res) {
    // 第一种方式
    res.locals.test = "test"; // 在渲染之前设置
    res.render('index', {
        title: '主页',
        user: req.session.user,
        posts: posts,
        success: req.flash('success').toString()
    });
});

app.get('/another', function (req, res) {
    // 第二种方式
    res.render('index', {
        title: '另一个页面',
        user: req.session.user,
        posts: posts,
        test: "testData",
        success: req.flash('success').toString()
    });
});

// 中间件示例
app.use(function (req, res, next) {
    var err = req.flash('error'),
        success = req.flash('success');
    res.locals.user = req.session.user;
    res.locals.error = err.length ? err : null;
    res.locals.success = success.length ? success : null;
    next();
});

app.listen(3000, () => console.log('Server running on port 3000'));

解释

  1. res.locals vs res.render中的属性

    • 第一种方式 (res.locals.test = "test";):
      • 这是在调用res.render之前设置的。
      • 它会将test添加到res.locals对象中,这样在后续的res.render调用中都可以访问到。
    • 第二种方式 (test: "testData"):
      • 这是在调用res.render时直接传入的对象属性。
      • 这个test属性只会在当前res.render调用中可用。
  2. 中间件中的res.locals

    • 在中间件中设置res.locals (app.use) 是为了在所有路由处理函数中共享数据。
    • 每次请求都会重新设置这些值,因此它们是针对每个请求的,而不是全局的。
    • 这样做的好处是可以在不同的路由处理函数之间共享数据,而不需要在每个路由处理函数中重复设置。

总结

  • res.locals 是一个为每个请求独立的对象,用于存储需要传递给模板的数据。
  • 在中间件中设置res.locals 可以让多个路由处理函数共享数据。
  • 直接在res.render调用中传入的属性仅在该请求中有效。

希望这能帮助你更好地理解res.locals的使用方法和不同场景下的差异。


<%=locals.testData%> 是整站全局的,一般存放用户全局信息,session和一些整站配置变量

<%=test%> 只是针对render下的页面 变量

前辈你好 app.locals不也是整站全局的吗?

前辈我查了下文档,关于app.use app.use([path], function) Use the given middleware function, with optional mount path, defaulting to “/”.

是不是说写在app.use中的res.locals数据只能在请求路径"/"对应的render页面中进行访问呢?

不只是 在“/” 所有地址都有效,app.locals,你是哪里看到的? 一般来说,设置整站的全局变量都这样设置 res.locals.current_user = req.session.user;

我google时上面说2.x->3.x的过程中app.helpers()和app.dynamicHelpers()已经被替换成了app.locals和res.locals,而且app.helpers我也试验过了 确实是全局的

http://cnodejs.org/topic/4f72d6478a04d82a3d2f2d51 这为小哥的这个帖子和我第一个帖子一样 如果没错的话我就先这么理解就好了

但是第二个还是没有明白=。=

res.locals 在 Node.js 的 Express 框架中用于存储当前 HTTP 响应(response)的本地变量。这些变量可以在渲染模板时使用。虽然你在两种不同的上下文中设置 res.locals 和响应对象中的属性都可以将数据传递给视图,但它们有一些关键的区别。

示例代码

const express = require('express');
const app = express();

app.set('view engine', 'ejs');

app.get('/', function(req, res) {
  // 方法一: 使用 res.locals
  res.locals.test = "test"; // 设置 res.locals 变量
  res.render('index', {
    title: '主页',
    user: req.session.user,
    posts: posts,
    success: req.flash('success').toString()
  });

  // 方法二: 直接设置响应对象的属性
  // res.render('index', {
  //   test: "testData", // 直接设置传递给视图的变量
  //   title: '主页',
  //   user: req.session.user,
  //   posts: posts,
  //   success: req.flash('success').toString()
  // });
});

app.listen(3000);

区别

  1. 作用域:

    • res.locals 是针对每次请求单独设置的。每个请求的 res.locals 都是独立的。
    • 直接设置 res.render 的参数则只对当前请求的响应有效。
  2. 生命周期:

    • res.locals 的生命周期与请求-响应周期相同。这意味着它在每个请求开始时都是一个新的对象。
    • 如果你需要在整个应用范围内共享一些数据,可以考虑使用 app.locals 或者挂载到 req 对象上。
  3. 中间件使用:

    • res.locals 通常用在中间件中,以便为后续的路由处理函数提供通用的数据。
    • 这种做法有助于保持代码的整洁和可维护性,特别是在需要为多个路由设置相同的变量时。
  4. 模板引擎访问:

    • 使用 res.locals 传递的数据在 EJS 模板中可以通过 locals 对象访问,即 <%= locals.test %>
    • 直接传递的数据可以直接通过变量名访问,即 <%= test %>

综上所述,虽然两种方法都可以实现数据传递,但使用 res.locals 更灵活,并且适合于中间件和跨请求共享数据的场景。

回到顶部