对于node.js开发指南中博客案例的修改实现(二)--代码
2015-06-26 20:57
656 查看
OK,废话少说,直接上代码
首先是app.js,里面很多与书中介绍的不同,不过看起来都很容易懂。首先是各种模块引用,然后就是使用session保存状态。
下面看看路由控制routes/index.js:代码中都有注释。其中需要注意的是中文参数的处理(先base64编码再解码)
在看一下models目录下的user.js,就是对mongodb的操作,保存查询
post.js:
主要的代码就这些了,跟书中的差别还是很大的,主要模块更新太快,书更新的速度跟不上技术的更新。
首先是app.js,里面很多与书中介绍的不同,不过看起来都很容易懂。首先是各种模块引用,然后就是使用session保存状态。
var express = require('express'); var path = require('path'); var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var session = require('express-session');//需要项目目录下npm install 安装模块 var MongoStore = require('connect-mongo')(session);//需要项目目录下npm install connect-mongo 安装模块 var settings = require("./settings"); var flash = require('connect-flash');//需要项目目录下npm install connect-flash 安装模块 var routes = require('./routes/index'); var users = require('./routes/users'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); // uncomment after placing your favicon in /public //app.use(favicon(__dirname + '/public/favicon.ico')); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(require('less-middleware')(path.join(__dirname, 'public'))); app.use(express.static(path.join(__dirname, 'public'))); app.use(flash()); app.use(session({ secret:settings.coolieSecret,//express.cookieParser() 是 Cookie 解析的中间件 //store参数为MongoStore实例,把会话信息存储到数据库中,以避免丢失。 store:new MongoStore({ db:settings.db }), resave:true, saveUninitialized:true })); //获取状态 app.use(function(req,res,next){ console.log("app.user local"); res.locals.user = req.session.user; res.locals.post = req.session.post; var error = req.flash('error'); res.locals.error = error.length?error:null; var success = req.flash('success'); res.locals.success = success.length?success:null; next(); }); app.use('/', routes); app.use('/users', users); // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // error handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); }); module.exports = app;
下面看看路由控制routes/index.js:代码中都有注释。其中需要注意的是中文参数的处理(先base64编码再解码)
var express = require('express'); var crypto = require('crypto'); var router = express.Router(); var settings = require("../settings"); var User = require("../models/user.js"); var Post = require("../models/post.js"); var iconv = require('iconv-lite'); /* GET home page. */ /* router.get('/', function(req, res, next) { res.render('index', { title: settings.title }); }); */ router.get('/',function(req,res){ Post.get(null,function(err,posts){ if(err){ posts = []; } res.render('index',{title:"首页",posts:posts}); }); }); router.get('/reg',checkNotLogin); router.get('/reg',function(req,res){ res.render('reg',{title:"注册"}); }); //注册事件处理 router.post('/reg',checkNotLogin); router.post('/reg',function(req,res){ console.log(req.body); //检测两次输入的密码是否相同 //req.body 就是 POST 请求信息解析过后的对象,例如我们要访问用户传递的password 域的值,只需访问 req.body['password'] 即可。 if(req.body['password-repeat'] != req.body['password']){ //req.flash 是 Express 提供的一个奇妙的工具,通过它保存的变量只会在用户当前和下一次的请求中被访问,之后会被清除, //通过它我们可以很方便地实现页面的通知和错误信息显示功能 req.flash('error','两次输入的口令不一致'); return res.redirect('/reg'); } //生成口令的散列值 //crypto 是 Node.js 的一个核心模块,功能是加密并生成各种散列, //使用它之前首先要声明 var crypto = require('crypto')。我们代码中使用它计算了密码的散列值。 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 is already exists. "; } if(err){ req.flash('error',err); console.log(err); return res.redirect('/reg'); } console.log("save"); //不存在则保存新用户 newUser.save(function(err){ if(err){ req.flash('error',err); console.log(err); console.log("save err"); return res.redirect('/reg'); } req.session.user = newUser; req.flash('success','注册成功'); return res.redirect('/'); }); }); }); //登录 router.get('/login',checkNotLogin); router.get('/login',function(req,res){ res.render('login',{title:'登录'}); }); //响应登录事件 router.post('/login',checkNotLogin); router.post('/login',function(req,res){ var md5 = crypto.createHash('md5'); var password = md5.update(req.body.password).digest('base64'); User.get(req.body.username,function(err,user){ if(!user){ req.flash('error','用户名不存在'); return res.redirect('/login'); } if(user.password != password){ req.flash('error','密码错误'); return res.redirect('/login'); } req.session.user = user; req.flash('success','登录成功'); return res.redirect('/'); }) }); //登出 router.get('/logout',checkLogin); router.get('/logout', function (req,res) { req.session.user = null; req.flash('success','登出成功'); res.redirect('/'); }); //发表处理 router.post('/post',checkLogin); router.post('/post',function(req,res){ var currentUser = req.session.user; var post = new Post(currentUser.name,req.body.post); post.save(function(err){ if(err){ req.flash('error',err); return res.redirect('/'); } req.flash('success','发表成功'); console.log('/u/'+currentUser.name); var pramsUserNnametemp = new Buffer(currentUser.name); var pramsUserNname = pramsUserNnametemp.toString('base64');//为了解决中文参数问题将参数base64编码,然后解码 // res.redirect('/u/'+currentUser.name); res.redirect('/u/'+pramsUserNname); }); }); router.get("/u/:user",function(req,res){ var uNametemp = new Buffer(req.params.user,'base64');//base64解码 var uName = uNametemp.toString(); //User.get(req.params.user, function(err,user){ User.get(uName, function(err,user){ if(!user){ req.flash('error','用户不存在'); res.redirect('/'); } Post.get(user.name,function(err,posts){ if(err){ req.flash('error',err); res.redirect('/'); } res.render('user',{title:user.name,posts:posts}); }); }); }); function checkLogin(req,res,next){ if(!req.session.user){ req.flash('error',"未登录"); return res.redirect('/login'); } next(); } function checkNotLogin(req,res,next){ if(req.session.user){ req.flash('error',"已登录"); return res.redirect('/'); } next(); } module.exports = router;
在看一下models目录下的user.js,就是对mongodb的操作,保存查询
var mongodb = require('./db'); function User(user){ this.name = user.name; this.password = user.password; }; module.exports = User; User.prototype.save = function save(callback){ //存入mongodb的文档 var user = { name:this.name, password:this.password }; mongodb.open(function(err,db){ if(err){ return callback(err); } //读取users集合 db.collection('users',function(err,collection){ if(err){ mongodb.close(); return callback(err); } //为name属性添加索引,新版本的ensureIndex方法需要一个回调函数 collection.ensureIndex('name',{unique:true},function(err){ //写入user文档 collection.insert(user,{safe:true},function(err,user){ mongodb.close(); callback(err,user); }); }); }); }); }; User.get = function get(username,callback){ mongodb.open(function(err,db){ if(err){ return callback(err); } //读取users集合 db.collection('users',function(err,collection){ if(err){ mongodb.close(); return callback(err); } //查找name属性为username的文档 collection.findOne({name:username},function(err,doc){ mongodb.close(); if(doc){ //封装文档为User对象 var user = new User(doc); callback(err,user); } else{ callback(err,null); } }); }); }); };
post.js:
var mongodb = require("./db"); function Post(username,post,time){ this.user = username; this.post = post; if(time){ this.time = time; } else{ this.time = new Date(); } }; module.exports = Post; Post.prototype.save = function save(callback){ //存入Mongodb的文档 var post = { username:this.user, post:this.post, time:this.time }; mongodb.open(function(err,db){ if(err){ return callback(err); } //读取posts集合 db.collection('posts',function(err,collection){ if(err){ mongodb.close(); return callback(err); } //为user属性添加索引 collection.ensureIndex('user',function(err){ //写入post文档 collection.insert(post,{safe:true},function(err,post){ mongodb.close(); callback(err,post); }); }); }); }); }; Post.get = function get(username,callback){ mongodb.open(function(err,db){ if(err){ return callback(err); } //读取posts集合 db.collection('posts',function(err,collection){ if(err){ mongodb.close(); return callback(err); } //查找user属性为username的文档,如果sername是null则全部匹配 var query = {}; if(username){ query.username = username; } collection.find(query).sort({time:-1}).toArray(function(err,docs){ mongodb.close(); if(err){ callback(err,null); } //封装posts为Post对象 var posts = []; docs.forEach(function(doc,index){ var post = new Post(doc.username,doc.post,doc.time); posts.push(post); }); callback(null,posts); }); }); }); };
主要的代码就这些了,跟书中的差别还是很大的,主要模块更新太快,书更新的速度跟不上技术的更新。
相关文章推荐
- Count Complete Tree Nodes算法详解
- leetcode-116-Populating Next Right Pointers in Each Node
- Node.js环境搭建
- Node.js程序在node-windows中不能运行
- node 安装socket.io
- nodejs npm常用命令
- Nodejs Request使用介绍
- ENode框架使用场景简述
- node mysql 连接池
- NodeJs Debug小工具的使用
- node.js 初体验
- webstorm配置node.js
- Leetcode#19 Remove Nth Node From End of List
- windows下nodejs环境配置
- [leetcode] Populating Next Right Pointers in Each Node II
- 《 Node.js项目实践:构建可扩展的Web应用》试读
- [leetcode] Populating Next Right Pointers in Each Node
- Node API
- 配置ssh时sshd不能启动解决办法
- Node.js学习