求教Nodejs express3.0中locals代替dynamicHelpers()的用法 route里修改res.locals.xx变量

求教Nodejs express3.0中locals代替dynamicHelpers()的用法 route里修改res.locals.xx变量

求教express3.0中locals代替dynamicHelpers()的用法 route里修改res.locals.xx变量:书上APP.JS代码

  app.dynamicHelpers({
      user: function(req, res) {
        return req.session.user;
      },
      error: function(req, res) {
        var err = req.flash('error');
        if (err.length)
          return err;
        else
          return null;
      },
      success: function(req, res) {
        var succ = req.flash('success');
        if (succ.length)
          return succ;
        else
          return null;
      },
    });

router里代码:`

exports.doReg = function(req, res) {
        	//检查密码
            if (req.body['password-repeat'] != req.body['password']) {
        		req.flash('error', '两次输入的密码不一致');
        		return res.redirect('/reg');
            }
          
            //生成md5的密码
            var md5 = crypto.createHash('md5');
            var password = md5.update(req.body.password).digest('base64');
            
            var newUser = new User({
        		name: req.body.username,
        		password: password,
            });
            
            //检查用户名是否已经存在
        	User.get(newUser.name, function(err, user) {
        		if (user)
        			err = 'Username already exists.';
        		if (err) {
        			req.flash('error', err);
        			console.log(res.locals.error);
        			return res.redirect('/reg');
        		}
        		//如果不存在則新增用戶
        		newUser.save(function(err) {
        			if (err) {
        				req.flash('error', err);
        				return res.redirect('/reg');
        			}
        			req.session.user = newUser;
        			req.flash('success', '注册成功');
        			res.redirect('/');
        		});
        	});
        
        };`

由于expresss3.0中已经去除dynamicHelpers()方法 现想用res.locals方法代替原来代码

现APP。JS替换代码

 app.use(function(req,res,next){
      
      res.locals.user=req.session.user;
      res.locals.error=req.flash('error').length?req.flash('error'):null;
      res.locals.success=req.flash('success').length?req.flash('success'):null;
        next();
    });
    
    app.get('/', routes.index);
    app.get('/u/:user', routes.user);
    app.post('/post', routes.post);
    app.get('/reg', routes.reg);
    app.post('/reg', routes.doReg);
    app.get('/login', routes.login);
    app.post('/login', routes.doLogin);
    app.get('/logout', routes.logout);

router里值无法传递给res.locals.xxx 因在论坛只找到原因是因为先执行的lcoals后执行route 所以无法再传递值res.locals.xxx ,给实在找不到解决方法,特请教各位高手指点一下如果解决传递值方法


18 回复

在Express 3.0 中,dynamicHelpers() 方法已被移除,开发者需要使用中间件来替代这种功能。你可以在 app.js 中定义一个中间件来设置 res.locals,这样可以确保在路由处理之前这些变量已经被设置好。

示例代码

首先,我们更新 app.js 文件,添加中间件来设置 res.locals

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

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

app.get('/', routes.index);
app.get('/u/:user', routes.user);
app.post('/post', routes.post);
app.get('/reg', routes.reg);
app.post('/reg', routes.doReg);
app.get('/login', routes.login);
app.post('/login', routes.doLogin);
app.get('/logout', routes.logout);

module.exports = app;

在这个中间件中,我们将 req.session.userreq.flash('error')req.flash('success') 的值分别赋给了 res.locals.userres.locals.errorres.locals.success。这使得这些变量可以在所有的路由处理函数中访问到。

更新路由处理函数

接着,我们需要更新路由处理函数 doReg,以确保在处理过程中正确地设置 req.flashres.locals 的值。

exports.doReg = function(req, res) {
    // 检查密码
    if (req.body['password-repeat'] != req.body['password']) {
        req.flash('error', '两次输入的密码不一致');
        return res.redirect('/reg');
    }

    // 生成md5的密码
    var md5 = crypto.createHash('md5');
    var password = md5.update(req.body.password).digest('base64');

    var newUser = new User({
        name: req.body.username,
        password: password,
    });

    // 检查用户名是否已经存在
    User.get(newUser.name, function(err, user) {
        if (user) {
            err = 'Username already exists.';
        }
        if (err) {
            req.flash('error', err);
            console.log(res.locals.error); // 这里应该能看到错误信息
            return res.redirect('/reg');
        }
        // 如果不存在则新增用户
        newUser.save(function(err) {
            if (err) {
                req.flash('error', err);
                return res.redirect('/reg');
            }
            req.session.user = newUser;
            req.flash('success', '注册成功');
            res.redirect('/');
        });
    });
};

总结

通过上述修改,我们利用中间件设置 res.locals 来替代 dynamicHelpers(),并在路由处理函数中正确地使用 req.flashres.locals。这样可以确保在任何路由处理之前,这些变量已经被正确设置,并且可以在模板或其他中间件中访问。


app.use(function(req,res,next){
  res.locals.user=req.session.user;
 ....   
 next();
});

放在

  app.use(app.router);

之前试试

我的笨方法里在每个路由都塞值。如: exports.login=function(req,res){ res.render(‘login’,{ user:req.session.user, success:req.flash(‘success’), error:req.flash(‘error’),

}); } 各位有好方法也晒一下吧。

我也是采用的这个方法、、、

用app.locals呢?不知道和res.locals的区别在那,在express的文档里看到的

app.locals Application local variables are provided to all templates rendered within the application. This is useful for providing helper functions to templates, as well as app-level data.

req.flash()方法在Express3.0中已经被删掉,要怎么用?

npm install connect-flash 安装这个模块

在 app.configure里加入 app.use(flash())

应该是顺序问题,我的app.js,如下 code ```app.configure(function(){ app.set(‘port’, process.env.port || 3000); app.set(‘views’, __dirname + ‘/views’); app.set(‘view engine’, ‘ejs’); app.engine(‘ejs’, require(‘ejs’).__express); //加载子模板文件 app.use(partials()); app.use(flash()); app.use(express.favicon()); app.use(express.bodyParser({ upload_dir: config.upload_dir })); app.use(express.methodOverride()); app.use(express.cookieParser(config.cookie_secret)); app.use(express.session()); app.use(app.router); app.use(express.static(__dirname+’/public’)); });

app.configure(‘development’, function(){ app.use(express.errorHandler({ dumpExceptions: true, showStack: true})); }); app.configure(‘production’, function(){ app.use(express.errorHandler()); }); app.use(function(req,res,next){ res.locals.user = req.session ? req.session.user:’’; res.locals.keyword = req.session ? req.session.keyword:’’; }); routes(app); //listen http.createServer(app).listen(3000, function(){ console.log(“express server listening on 3000” ; });```

在app.js 添加

app.use(function (req, res, next) {
    res.locals.error = req.flash('error');
    res.locals.success = req.flash('success');
    res.locals.user = req.session.user;
    next();
});

就可以实现全局了。

前端模版这样做判断

<% if (success && success.length ) { %>
    <div class="alert alert-success">
        <a class="close" data-dismiss="alert" href="#">×</a>
        <<strong><%= success %></strong>
    </div>
<% } %>

好像只能放在这句前面才不会页面报错 但是仍然获取不到,req.flash(‘error’)值是空的…

我的req.flash(‘success’)获取到值打印出来是[] 处理的index.js那边没有错并能获取到,传到前端就是[]了…

搞明白了 req.flash(‘error’)执行一次就会消失。参见http://cnodejs.org/topic/5076d6c725bf229e202c6c22

require(“connect_flash”)

flash 闪出 的意思,PHP里面很多框架都有这个功能,CI TP Yii框架里面都有的

好案例

楼主给的代码是有错误的。 app.use(function(req,res,next){

  res.locals.user=req.session.user;
  res.locals.error=req.flash('error').length?req.flash('error'):null;   // 调用req.flash('error') 返回值,随后立即情况error属性值。在后面的       第二次调用,就会返回一个空集合,所以模版渲染的时候就得不到数据。正确做法应该先用一个过渡变量拷贝一份
  res.locals.success=req.flash('success').length?req.flash('success'):null;
    next();
});

在Express 3.0中,dynamicHelpers() 方法已被弃用,推荐使用中间件来设置 res.locals。根据你的需求,可以使用一个中间件来设置 res.locals 变量,以确保这些变量在每个请求中都可用。

以下是修改后的代码示例:

APP.JS 文件

var express = require('express');
var app = express();
var routes = require('./routes');

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

app.get('/', routes.index);
app.get('/u/:user', routes.user);
app.post('/post', routes.post);
app.get('/reg', routes.reg);
app.post('/reg', routes.doReg);
app.get('/login', routes.login);
app.post('/login', routes.doLogin);
app.get('/logout', routes.logout);

app.listen(3000);

路由文件中的 doReg 方法

exports.doReg = function(req, res) {
  // 检查密码
  if (req.body['password-repeat'] != req.body['password']) {
    req.flash('error', '两次输入的密码不一致');
    return res.redirect('/reg');
  }

  // 生成md5的密码
  var md5 = crypto.createHash('md5');
  var password = md5.update(req.body.password).digest('base64');

  var newUser = new User({
    name: req.body.username,
    password: password,
  });

  // 检查用户名是否已经存在
  User.get(newUser.name, function(err, user) {
    if (user) {
      err = 'Username already exists.';
    }
    if (err) {
      req.flash('error', err);
      console.log(res.locals.error); // 确保这里的值已经被设置
      return res.redirect('/reg');
    }
    // 如果不存在则新增用户
    newUser.save(function(err) {
      if (err) {
        req.flash('error', err);
        return res.redirect('/reg');
      }
      req.session.user = newUser;
      req.flash('success', '注册成功');
      res.redirect('/');
    });
  });
};

解释

  1. 中间件:我们在 app.use 中定义了一个中间件,该中间件会在每个请求处理之前运行,并设置 res.locals 变量。
  2. 路由处理:在 doReg 方法中,我们通过 req.flash 设置错误和成功消息,并将这些消息存储到 res.locals 变量中。
  3. 确保值被设置:在 console.log(res.locals.error) 中,你可以看到 res.locals.error 已经被正确设置。

这种方法确保了在每个请求中都可以访问 res.locals 变量,而不需要依赖于 dynamicHelpers 方法。

回到顶部