这本书中关于开发微博小功能所用到的 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('/');
});
嗯,3Q,我也不知道怎么一发布就乱掉啦。 是在我请求http://localhost/页面中报的, 我的问题时我不知道的时在express 3.x中不用视图助手的怎么实现数据的传输,把登陆信息还有提示信息输出到页面上?
@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:‘注册成功’});哎,敲着本书上代码被折腾死拉,现在遇到错就一笔带过,大概理解就行拉
@kingzyl 本人小白一个,刚接触node,可以问一下这个问题您是怎么解决的吗?