使用express4.x版Jade模板以及mysql重写《nodejs开发指南》微博实例
Posted 余朝忠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用express4.x版Jade模板以及mysql重写《nodejs开发指南》微博实例相关的知识,希望对你有一定的参考价值。
最近阅读《nodejs开发指南》一书,书是不错的,然而其微博代码示例用的是express3.x,用些过时了,运行代码出现不少bug(我电脑安的是express4.x),于是用express4.x+jade模板重写一遍(原代码使用的是ejs模板)。因为想体验一下node结合mysql开发,于是将mongodb改为mysql。下面进入正文
1、安装express框架与生成器:
2、进入网站目录,创建项目:
3、安装中间件与依赖项:
package.json如下
单独安装时记得加上--save,便于项目迁移重新安装中间件。
4、启动项目:
先安装supervisor,启动实时监控文件修改并重新启动服务器,这样就不用每次修改文件都重新启动服务器。
启动项目
5、看看我的项目目录
configs放配置文件,写法遵循commonjs规范。
install放安装所需文件,安装时读取sql代码连接数据库创建数据表并插入数据,有后台管理时创建保存管理员账号,完成安装时声称lock.txt文件。方便项目迁移。
log放日志文件,access是访问日志,error是错误日志
public放静态资源文件。
models为模型操作文件,相当于为MVC中的M;routes为路由文件,相当于为MVC中的C以及路由解析分发;view为V,视图层。
utils防止工具类文件以及第三方工具类文件
cluster.js为充分调用电脑多核资源所写,根据核数量创建相应数量进程运行app.js。运行 supervisor cluster.js
6、下面看源代码:
cluster.js
var cluster = require(\'cluster\'); var os = require(\'os\'); var cpuNum = os.cpus().length; var workers = {}; if(cluster.isMaster){ //主进程 //当一个进程结束,重启工作进程 cluster.on(\'death\',function(worker){ delete workers[worker.pid]; worker = cluster.fork(); workers[worker.pid] = worker; }) //根据CPU数量创建相应数量的进程 for(var i=0; i<cpuNum;i++){ var worker = cluster.fork(); workers[worker.pid] = worker; } }else{//工作进程 var app = require(\'./app\'); app.listen(3000); } //当主进程终止,关闭所有主进程 process.on(\'SIGTERM\',function(){ for(var pid in workers){ precess.kill(pid); } process.exit(0); })
app.js
var express = require(\'express\'); var logger = require(\'morgan\'); var fs = require(\'fs\'); var fileStreamRotator = require(\'file-stream-rotator\') var cookieParser = require(\'cookie-parser\'); var session = require(\'express-session\'); var bodyParser = require(\'body-parser\'); var path = require(\'path\'); var favicon = require(\'serve-favicon\'); var flash = require(\'connect-flash\'); var index = require(\'./routes/index\'); var user = require(\'./routes/user\'); var app = express(); // 设置模板引擎与模板目录 app.set(\'views\', path.join(__dirname, \'views\')); app.set(\'view engine\', \'jade\'); // 日志输出到文件系统,每日一个日志文件 var accessLogDirectory = __dirname + \'/logs/access\'; fs.existsSync(accessLogDirectory) || fs.mkdirSync(accessLogDirectory); var errorLogDirectory = __dirname + \'/logs/error\'; fs.existsSync(errorLogDirectory) || fs.mkdirSync(errorLogDirectory); var accessLogStream = fileStreamRotator.getStream({ filename:accessLogDirectory+\'/access-%DATE%.log\', frequency:\'daily\', verbose:false }) app.use(logger(\'combined\',{stream:accessLogStream})); // 设置错误日志文件地址 var errorLogStream = fs.createWriteStream(errorLogDirectory+\'/error.log\',{\'flags\':\'a\'}); //将请求体放入request.body app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); //处理cookie app.use(cookieParser()); //处理session app.use(session({ secret:\'testexpress\', cookie: { maxAge: 60000 }, resave: true, saveUninitialized: true })) // 设置icon图标 app.use(favicon(path.join(__dirname, \'public\', \'favicon.ico\'))); //flash支持 app.use(flash()); //静态文件借口 app.use(express.static(path.join(__dirname, \'public\'))); // 挂靠路由中间件 app.use(\'/\', index); app.use(\'/index\', index); app.use(\'/user\', user); //404错误处理句柄 app.use(function(req, res, next) { var err = new Error(\'Not Found\'); err.status = 404; next(err); }); //错误处理 app.use(function(err, req, res, next) { var error = (req.app.get(\'env\') === \'development\' )? err : {}; //写错误日志 var errorMes = \'[\'+Date()+\']\'+req.url+\'\\n\'+\'[\'+error.stack+\']\'+\'\\n\'; errorLogStream.write(errorMes); // 写回错误处理代码 res.status(err.status || 500); res.render(\'error\',{\'message\':err.message,\'error\':error}); }); //防止服务器自启动。只许在外部模块调用 if(!module.parent){ app.listen(3000,function(){ console.log("Server listening on port %d in %s",3000,app.settings.env); }); } module.exports = app;
routes/index.js
var express = require(\'express\'); var router = express.Router(); var News = require(\'../models/news\'); /* GET home page. */ router.get(\'/\', function(req, res, next) { News.get(null,function(err,news){ var user = null; if(err){ news = []; } if(req.session.user){ user = req.session.user; } res.render(\'index/index\', { title: \'微博首页\', news:news, user:user }); }) }); module.exports = router;
routes/user.js
var express = require(\'express\'); var router = express.Router(); var User = require(\'../models/user\'); var News = require(\'../models/news\'); var crypto = require(\'crypto\'); //访问用户页面 router.get(\'/:user\', function (req, res) { User.get(req.params.user, function (err, user) { if (!user) { console.log(req.session); req.flash(\'error\', \' 用户不存在\'); return res.redirect(\'/\'); } console.log(user); News.get(user.username, function (err, news) { if (err) { req.flash(\'error\', err); return res.redirect(\'/\'); } res.render(\'user/index\', { username: user.username, news: news }); }); }); }); //访问注册页 router.get("/reg",checkNotLogin); router.get("/reg",function(req,res){ res.render(\'reg\',{ \'title\':\'用户注册\' }) }) //提交注册信息 router.post(\'/reg\',checkNotLogin); router.post(\'/reg\',function(){ if(req.body[\'password-repeat\']!=req.body[\'password\']){ req.flash(\'error\',\'两次输入的口令不一致\'); return res.redirect(\'/reg\'); } 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); return res.redirect(\'/reg\'); } // 如果不存在则新增用户 newUser.save(function (err) { if (err) { req.flash(\'error\', err); return res.redirect(\'/reg\'); } req.flash(\'success\', \' 注册成功\'); res.redirect(\'/login\'); }); }); }) //用户访问登录页 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\', \' 登入成功\'); res.redirect(\'/\'); }); }) //用户退出 router.get(\'/logout\',checkLogin); router.get(\'/logout\', function (req, res) { req.session.user = null; req.flash(\'success\', \'登出成功\'); res.redirect(\'/\'); }); //找回密码 router.get(\'/getPwd\',checkNotLogin); router.get(\'/getPwd\',function(req,res){ res.render(\'getpwd\', { title: \'密码找回\', }); }) router.post(\'/getPwd\',checkNotLogin); router.post(\'/getPwd\',function(req,res){ User.get(req.body.username, function (err, user) { if (!user) { req.flash(\'error\', \' 用户不存在\'); return res.redirect(\'/getPwd\'); } req.flash(\'success\', \'成功找回密码:\'+user.password); res.redirect(\'/login\'); }); }) //发表微博 router.post(\'/news\', checkLogin); router.post(\'/news\', 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\', \' 发表成功\'); res.redirect(\'/u/\' + currentUser.name); }); }); 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;
configs/settings.js
(function(){
var settings;
settings = {
mysql:{
host:\'localhost\',
prot:\'3306\',
user:\'root\',
password:\'\',
database:\'node_microblog\'
},
mongodb:{
host:\'localhost\',
prot:\'27017\',
user:\'root\',
password:\'\',
database:\'node_microblog\'
}
}
module.exports = settings;
})()
utils/database.js
(function(){ var settings = require(\'../configs/settings\'); var mysql = require(\'mysql\'); var client = null; var default_sql = require exports.getDbCon = function(){ try{ if(client){ client = mysql.createConnection(settings.mysql); client.connect(); }else{ client = new mysql.createConnection(settings.mysql); client.connect(); } }catch(_error){ throw _error; } return client; } exports.install = function(){ } })()
models/news.js
var database = require(\'../utils/database\'); mysql = database.getDbCon(); function News(username,content,time){ this.username = username; this.content = content; if (time) { this.time = time; } else { this.time = new Date (); console.log(this.time); } } //保存消息 News.prototype.save = function(callback){ var sql = "select id from user where username = \'"+this.username+"\'"; mysql.query(sql,function(err,results,fields){ if(err){ throw err; } if(results){ this.uid = results[0].id; } var news = { username: this.uid, content: this.conetnt, time: this.time }; sql = "insert into user(uid,content,time) values(?,?,?)"; mysql.query(sql,[news.uid,news.content,news.time],function(err,results,fields){ if (err) { throw err; } else { //返回用户id return callback(err,fields); } }) }) }; //获取消息 News.get = function(username,callback){ var sql ="select * from news"; if( username){ sql +=" join user on user.id=news.uid where username=\'"+username+"\'"; } mysql.query(sql,function(err,results,fields){ if(err){ throw err; }else{ callback(err,results,fields); } }) } module.exports = News;
models/user.js
var database = require(\'../utils/database\'); mysql = database.getDbCon(); function User(user){ this.username = user.username; this.password = user.password; } //保存用户 User.prototype.save = function(callback){ var user = { username: this.username, password: this.password }; var sql ="insert into user (username,password) values(?,?)"; mysql.query(sql,[user.username,user.password],function(err,results,fields){ if (err) { throw err; } else { //返回用户id return callback(err,fields); } }); }; //获取用户 User.get = function(id,callback){ var sql = "select * from user where id=\'"+id+"\'"; mysql.query(sql,function(err,results,fields){ if(err){ throw err; }else{ callback(err,results[0],fields); } }) } module.exports = User;
源代码下载:https://github.com/yujon/node_microblog
以上是关于使用express4.x版Jade模板以及mysql重写《nodejs开发指南》微博实例的主要内容,如果未能解决你的问题,请参考以下文章
《nodejs开发指南》微博实例常见错误汇总express4.x.x+jade
express 4.0x 用ejs妫傻腶pp.js没有app.configure,怎么弄