有在看《Node.js开发指南》这本书的吗?关于书上的一个问题,求大神们指点迷津啊?
发布于 1年前 作者 kingzyl 1404 次浏览

这本书中关于开发微博小功能所用到的 web 开发框架是 express 2.x,而我在练习代码的时候安装的是 express.3.x,所以里面的视图助手 app.dynamicHelpers() 方法和 req.flash() 都被移除,百度了一下对于试图助手可以使用 res.locals.xxx 代替,flash 方法的问题可以安装 connect-flash 插件解决。本社区一哥们给出一段代码所加在 app.js 中其它文件都不用改,代码如下:

var flash = require('connect-flash');
app.use(flash());
app.use(function(req, res, next){
  res.locals.user = req.session.user;
  var err = req.flash('error');
  if(err.length)
    res.locals.error = err;
  else
    res.locals.error = null;
  var succ = req.flash('success');
  if(succ.length)
    res.locals.success = succ;
  else
    res.locals.success = null;
  next();
});

这样服务器可以跑起来,但是打开页面的时候报错 user not defined 错误,我很纳闷,百思不得其解,刚接触 Node.js 所以请各位多多指教啊,下面贴一下相关文件的代码供你们参考,希望能把解了这个疑惑…3Q。。

layout.ejs 中关键代码如下:

 <div class="navbar navbar-fixed-top"> 
          <div class="navbar-inner"> 
        <div class="container"> 
          <a class="btn btn-navbar"  data-toggle="collapse" data-target=".nav-collapse"> 
            <span class="icon-bar"></span> 
            <span class="icon-bar"></span> 
            <span class="icon-bar"></span> 
          </a> 
          <a class="brand" href="/">Microblog</a> 
          <div class="nav-collapse"> 
            <ul class="nav"> 
              <li class="active"><a href="/">首页</a></li> 
              <% if(!user){ %>
              <li><a href="/login">登陆</a></li> 
              <li><a href="/reg">注册</a></li> 
              <% }else{ %>
                      <li><a href="/logout">登出</a></li> 
              <% } %>
            </ul> 
          </div> 
        </div> </div> </div>

    <div id="container" class="container-fluid"> 
        <% if (success) { %> 
        <div class="alert alert-success"> <%=success %> </div> 
        <% } %> 
        <% if (error) { %> 
        <div class="alert alert-error">  <%=error %>   </div> 
        <% } %>
             <%- body %> 

routes/index.js 中关键代码如下:

app.post('/login',function(req, res){
   var password = md5.update(req.body.password).digest('base64'); 
   
  User.get(req.body.username, function(err, user) { 
    if (!user) { 
      req.flush("error",'用户不存在'); 
      return res.redirect('/login'); 
    } 
    if (user.password != password) { 
       req.flush("error",'用户口令错误'); 
      return res.redirect('/login'); 
    } 
    req.session.user = user; 
     req.flush("success",'登入成功'); 
    res.redirect('/'); 
  });
});

app.get('/logout',function(req, res){
   req.session.user = null; 
   req.flush("success",'登出成功'); 
  res.redirect('/'); 
});
26 回复

帮楼主编辑了下格式… 没看懂 user not defined 是在页面报的还是命令行里?

嗯,3Q,我也不知道怎么一发布就乱掉啦。 是在我请求http://localhost/页面中报的, 我的问题时我不知道的时在express 3.x中不用视图助手的怎么实现数据的传输,把登陆信息还有提示信息输出到页面上?

@kingzyl 论坛用了 Markdown 格式, Google 下中文的文档看下~ 终端报错是 JS 环境的里 user 不存在, 页面上的话应该是 ejs 模版里数据不存在. express 表示我用得不多… 别的同学看吧

@jiyinyiyong 嗯,Markdown听说过,有时间在研究吧,我呆现在把这个问题给处理掉

@youxiachai 看了,可是用了老是报错啊,求指点啦,亲…

@youxiachai 难道非要逼我把express 3.x给卸了,装上2.x吗???

页面上的user改成locals.user试试

哈哈,是可以的,现在页面不报错啦,但是在index.js页面报has no flash method方法错误,于是我我ejs还有app.js文件中的flash方法换成了res.locals.xxx来传值,但是res.locals.error还有res.locals.success的值始终为null ,如下是app.js页面中新调整关键代码: app.use(function(req, res, next){ res.locals.user = req.session.user; var err = res.locals.error; console.log("Error:-------- “+err+” ---------"); if(err) res.locals.error = err; else res.locals.error = null;

var succ = res.locals.success; console.log("Success:-------- “+succ+” ---------"); if(succ) res.locals.success = succ; else res.locals.success = null; next(); });

求大神解答,谢啦!

@kingzyl res.locals是本地变量,我觉得如果你的success和error变量不是全局的,还是不要存在locals里,可以直接返回到某一次请求所对应的页面,就像:res.render('index’,{success: success, error, error});我觉得这样会好点,不然的话你在某个页面改动了success/error的值可能会影响当前页面的值。这只是我的个人理解,我也是刚开始学的

@maiwenan 哦,学习啦,我只是照着书上的代码练习一下,不过老是报错,如果不解决掉,后面的书上的案例照样没法做,所以很是捉急啊,如果用res.render()的方法的话,好像每次进入首页都也传递layout.ejs模版中<%=title%>、<%=success%>、<%=error%>、这样貌似更麻烦啊

恩恩,是有点 var err = res.locals.error; console.log("Error:-------- “+err+” ---------"); if(err) res.locals.error = err; else res.locals.error = null;

这段代码的if判断是不是有点多余啊

我也感觉多余啦,不过貌似js中还有个undefinded类型吧

有电子版没?

呵呵,我看的就是电子版的…

@kingzyl 恩恩,如果用locals.error的话似乎也要在每个路由中对error和success赋值。

@maiwenan 好吧,我现在用res.render()方法,页面之间是可以传值啦,不过注册和登录时报500 TypeError: HashUpdate fail 。。。。哎,真是一波未平一波又起啊…

@kingzyl 是crypto var md5 = crypto.createHash(‘md5’);的那有问题吧?貌似对同一个md5重复调用md5.update(“1234”).digest(‘base64’)这个方法就会报这个错了

@maiwenan 嗯,果然是这个原因,这本书还木有看完就快被它给折腾死拉,哎…对node.js的热情都减了不少

@kingzyl这本书用的都是旧版本了,可以买深入浅出nodejs,正在预售,网上搜了几章看,觉得还不错,还有nodejs in action,都还不错,不过是英文版的。

@maiwenan 深入浅出好像12月份才可以买吧…你说node.js的未来会超过php这样的语言吗?

@kingzyl这个可难说了,各有优缺点

哥们!我也报错了,补过是在注册的时候!一直报错!不知道什么情况 events.js:72 throw er; // Unhandled ‘error’ event ^ ReferenceError: user is not defined at J:\studyNow\microblog\routes\index.js:69:7 at J:\studyNow\microblog\node_modules\user.js:53:6 at J:\studyNow\microblog\node_modules\mongodb\lib\mongodb\collection.js:953: 5 at J:\studyNow\microblog\node_modules\mongodb\lib\mongodb\cursor.js:683:35 at Cursor.close (J:\studyNow\microblog\node_modules\mongodb\lib\mongodb\curs or.js:903:5) at Cursor.nextObject (J:\studyNow\microblog\node_modules\mongodb\lib\mongodb \cursor.js:683:17) at commandHandler (J:\studyNow\microblog\node_modules\mongodb\lib\mongodb\cu rsor.js:658:14) at J:\studyNow\microblog\node_modules\mongodb\lib\mongodb\db.js:1670:9 at Server.Base._callHandler (J:\studyNow\microblog\node_modules\mongodb\lib
mongodb\connection\base.js:382:41) at J:\studyNow\microblog\node_modules\mongodb\lib\mongodb\connection\server. js:472:18

下面贴出来index.js

/*

  • GET home page. */

exports.index = function(req, res){ res.render('index’, { title: ‘Express’ , date : new Date().toString()}); }; exports.hello = function(req,res){ //1.为函数指定页面模板【也就是跳转的页面】 //render函数有两个参数:第一个参数是模板名称,即为views目录下的js文件名,第二个参数为传递给模板的数据,用于模板翻译 res.render("index",//render给予调用模板引擎,并将其产生的页面直接返回给客户端 {title:’用户列表-后台管理系统’, date : new Date().toString(), layout:’layout_admin’}); //2.为函数指定头页面,其中包括样式css文件【页面样式,在public/stylesheets中添加新的css文件】

//res.send('The time is’+new Date().toString());//如果上面指定了模板页面,则下面的res.send()发送客户端数据将失效。数据应该都写在页面中 //res.render('index’,{title:’用户列表-后台管理系统’,layout:’admin’}); };

//exports.user = function(req,res){//用户信息 //} //exports.post = function(req,res){//发表消息 //}

//exports.reg = function(req,res){ //} //exports.doReg = function(req,res){ //}

//exports.login = function(req,res){ //} //exports.doLogin = function(req,res){ //} //exports.logout = function(req,res){ //} //exports.doLogout = function(req,res){ //}

module.exports = function(appExpress){ appExpress.get('/’,function(req,res){ res.render('index’,{title:’首页’}); });

appExpress.get('/reg’,function(req,res){ res.render('reg’,{title:’用户注册’}); });

appExpress.post('/reg’,function(req,res){ if(req.body[‘password-repeat’]!=req.body[‘password’]){ // req.flash(‘error’,’两次输入的口令不一致’); return res.redirect(‘/reg’); } var crypto = require(‘crypto’); var md5 = crypto.createHash(“md5”); var password = md5.update(req.body.password).digest(‘base64’); var User = require(‘…/node_modules/user’); var newUser = new User({ name:req.body.username, password:password, });

User.get(newUser.name,function(req,res){ if(user){ err = 'Username already exists’; } if(err){ // req.flash('error’,err); return res.redirect(‘/reg’); }

newUser.save(function(err){ if(err){ // req.flash('error’,err); return res.redirect(‘/reg’); } req.session.user = new User; // req.flash(‘success’,’注册成功’); res.redirect(‘/’); }); });

});

};

var User = require(‘…/node_modules/user’); 这里的node_modules是放user.js的文件夹

@lixld 我看你貌似抛弃了req.flash方法来传值是直接通过res.redirect跳转的,没传值当然是undfined啦,我是通过res.render()方法传值和跳转的,比如注册成功res.render('index’,{title:’首页’,user:null,error:null,success:’注册成功’});哎,敲着本书上代码被折腾死拉,现在遇到错就一笔带过,大概理解就行拉

回到顶部