最近看BYVoid的《node.js开发指南》这一本书,在看到博客开发实践那一章节时,发现其版本为express2.x的,而我使用的是express4.x版本的,好多API改变以及用法的改变导致完全照搬则不能运行,所以就重写了一下(也就是改了改API而已)。我也是才刚开始接触node.js,修改的不足之处,欢迎大家指点,和大家一起学习。
我使用的是Webstorm编辑器,该编辑器可以创建node.js的express工程,很好使用,模板我选择的是ejs,同时数据库使用的是mongodb。关于node.js的环境搭建不需要多说,百度一下,你就知道,好吧。
好吧,废话我也不说了,我就上我的源码了!
package.json:
{
"name": "nodejsProject",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.15.1",
"cookie-parser": "~1.4.3",
"debug": "~2.2.0",
"ejs": "~2.4.1",
"express": "~4.13.4",
"morgan": "~1.7.0",
"serve-favicon": "~2.3.0",
"mongodb": "~2.2.7", //编辑加入
"connect-mongo": ">=0.1.7",<span style="font-family: Arial, Helvetica, sans-serif;">//编辑加入</span>
"express-session":">=1.0.4",<span style="font-family: Arial, Helvetica, sans-serif;">//编辑加入</span>
"connect-flash":"*"<span style="font-family: Arial, Helvetica, sans-serif;">//编辑加入</span>
}
}
当时我在编写的时候发现,我不在dependecies中加入什么connext-mongo等模块,项目也可以运行。具体原因未去探究!
app.js:
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');
var MongoStore = require('connect-mongo')(session);
var settings = require('./settings.js');
var flash = require('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');
app.use(flash());
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'views')));
app.use(session({
secret : settings.cookieSecret,
cookie:{maxAge:1000*60*60*24*30},
store : new MongoStore({
<strong>url : 'mongodb://localhost/myblog'</strong>
}),
resave:false,
saveUninitialized:true
}));
app.use('/', routes);
app.use('/users', users);
app.use('/u/:user',routes);
app.use('/post',routes);
app.use('/reg',routes);
app.use('/login',routes);
app.use('/logout',routes);
// 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;
上面的加粗代码段(url : 'mongodb://localhost/myblog')中的myblog是使用mongodb创建的myblog数据库。而且关于动态提示的那个中间件我并没有去使用,我是在路由中通过传值也达到了效果。
index.js(路由):
var express = require('express');
var User = require('../user.js');
var Post = require('../post.js');
var crypto = require('crypto');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
Post.get(null, function (err,posts) {
if(err){
posts = [];
}
res.render('index', { title: '首页',
user: req.session.user,
success : req.flash('success').toString(),
error : req.flash('error').toString(),
posts:posts});
});
});
router.get('/u/:user', function (req, res, next) {
User.get(req.params.user, function (err,user) {
if(!user){
req.flash('error','用户不存在');
return res.redirect('/');
}
Post.get(user.name, function (err,posts) {
if(err){
req.flash('error',err);
return res.redirect('/');
}
console.log(posts);
res.render('user',{
title: user.name,
user:user.name,
posts: posts,
success : req.flash('success').toString(),
error : req.flash('error').toString()
});
});
});
});
router.post('/post', checkLogin);
router.post('/post', function (req,res,next) {
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);
});
});
router.get('/reg', function (req ,res ,next) {
res.render('reg',{title:"用户注册",
user: req.session.user,
success : req.flash('success').toString(),
error : req.flash('error').toString()
});
});
router.post('/reg', function (req, res, next) {
if(!req.body.username ||req.body['password-repeat'] || req.body['password']){
req.flash('error', '下列输入框都不能为空!');
return res.redirect('/reg');
}
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.session.user = newUser;
req.flash('success', '注册成功');
res.redirect('/');
});
});
});
router.get('/login', checkNotLogin);
router.get('/login', function (req ,res ,next) {
res.render('login', {title: '用户登入',
user: req.session.user,
success : req.flash('success').toString(),
error : req.flash('error').toString()
});
});
router.post('/login', function (req, res, next) {
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('/u/'+user.name);
})
});
router.get('/logout', checkLogin);
router.get('/logout', function (req, res, next) {
req.session.user = null;
req.flash('success', '成功退出');
res.redirect('/');
});
module.exports = router;
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();
}
settings.js
module.exports = {
cookieSecret : 'myblog',
db : 'myblog',
host : 'localhost',
port : 27017
};
var setttings = require('./settings.js');
var mongodb = require('mongodb');
var server = new mongodb.Server('localhost', 27017,{auto_reconnect : true});
var db = new mongodb.Db(setttings.db, server, {safe:true});
module.exports = db;
这个连接数据库的方法和原作者不同,原作者那个方法也可以使用。
user.js:
var mongodb = require('./db.js');
function User(user){
this.name = user.name;
this.password = user.password;
}
module.exports = User;
User.prototype.save = function save(callback){
var user = {
name : this.name,
password : this.password
};
mongodb.open(function (err,db) {
if(err){
return callback(err);
}
db.collection('users', function (err, collection) {
if(err){
mongodb.close();
return callback(err);
}
collection.ensureIndex('name', {unique : true});
collection.insert(user,{safe: true}, function (err, user) {
mongodb.close();
if(err){
return callback(err);
}
callback(err,user[0]);
});
});
});
};
User.get = function (username,callback) {
mongodb.open(function (err,db) {
if(err){
return callback(err);
}
db.collection('users', function (err,collection) {
if(err){
mongodb.close();
return callback(err);
}
collection.find({name: username}).toArray(function (err, doc) {
if(err){
callback(err);
}
mongodb.close();
//console.log(doc);
if(doc && doc.length){
var user = new User(doc[0]);
callback(err, user);
}else{
callback(err,null);
}
});
});
});
};
post.js:
var mongodb = require('./db.js');
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 (callback) {
var post = {
user : this.user,
post : this.post,
time : this.time
};
mongodb.open(function (err,db) {
if(err){
return callback(err);
}
db.collection('posts', function (err,collection) {
if(err){
mongodb.close();
return callback(err);
}
collection.ensureIndex('user');
collection.insert(post,{safe: true}, function (err, post) {
mongodb.close();
callback(err,post);
});
});
});
};
Post.get = function (username, callback) {
mongodb.open(function (err,db) {
if(err){
mongodb.close();
return callback(err);
}
db.collection('posts', function (err,collection) {
if(err){
mongodb.close();
return callback(err);
}
var query = {};
if(username){
query.user = username;
}
collection.find(query).sort({time:-1}).toArray(function (err,docs) {
mongodb.close();
if(err){
return callback(err,null);
}
var posts = [];
docs.forEach(function (doc, index) {
var post = new Post(doc.user,doc.post,doc.time);
posts.push(post);
});
callback(err,posts);
});
});
});
};
ejs模板的代码,我修改了蛮多,这里就不上传了,如果需要的话,联系我单独发(邮箱:zhongshou.bo@163.com)。(什么!!你没有github??不好意思,我目前还木有!)