原教程 https://github.com/nswbmw/N-blog/wiki/_pages的第一章。因为版本号等的原因,在原教程基础上稍加修改就可以实现。

环境:

win7旗舰版64位

Node.js:0.10.31

mongodb:2.6.4

express:3.×

效果:

注冊界面:

登录界面:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZG9uZ3NoYW9zaHVhaQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

登录成功:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZG9uZ3NoYW9zaHVhaQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

发表博客:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZG9uZ3NoYW9zaHVhaQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

发表成功:

源码:

blog/

blog/package.json

{
"name": "blog",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "3.16.7",
"ejs": "*",
"mongodb":"*",
"connect-mongo":"*",
"connect-flash":"*"
}
}

blog/app.js

/**
* Module dependencies.
*/ var express = require('express');
var routes = require('./routes');
var http = require('http');
var path = require('path');
var MongoStore=require('connect-mongo')(express);
var settings=require('./settings');
var flash=require('connect-flash');
var app = express(); // all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(flash());
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride()); app.use(express.static(path.join(__dirname, 'public')));
app.use(express.cookieParser());
app.use(express.session({
secret: settings.cookieSecret,
key: settings.db,//cookie name
cookie: {maxAge: 1000 * 60 * 60 * 24 * 30},//30 days
store: new MongoStore({
db: settings.db
})
}));
//此句写在session前面就会出错 为啥捏
app.use(app.router); // development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
} routes(app); http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});

blog/settings.js

module.exports={
cookieSecret:'myblog',
db:'blog',
host:'localhost'
};

blog/models/

blog/models/db.js

var settings=require('../settings'),
Db=require('mongodb').Db,
Connection=require('mongodb').Connection,
Server=require('mongodb').Server;
module.exports=new Db(settings.db,new Server(settings.host,Connection.DEFAULT_PORT), {safe: true});

blog/models/post.js

var mongodb = require('./db');

function Post(name, title, post) {
this.name = name;
this.title = title;
this.post = post;
} module.exports = Post; //存储一篇文章及其相关信息
Post.prototype.save = function(callback) {
var date = new Date();
//存储各种时间格式。方便以后扩展
var time = {
date: date,
year : date.getFullYear(),
month : date.getFullYear() + "-" + (date.getMonth() + 1),
day : date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate(),
minute : date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " " +
date.getHours() + ":" + (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes())
}
//要存入数据库的文档
var post = {
name: this.name,
time: time,
title: this.title,
post: this.post
};
//打开数据库
mongodb.open(function (err, db) {
if (err) {
return callback(err);
}
//读取 posts 集合
db.collection('posts', function (err, collection) {
if (err) {
mongodb.close();
return callback(err);
}
//将文档插入 posts 集合
collection.insert(post, {
safe: true
}, function (err) {
mongodb.close();
if (err) {
return callback(err);//失败!返回 err
}
callback(null);//返回 err 为 null
});
});
});
}; //读取文章及其相关信息
Post.get = function(name, 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);
}
var query = {};
if (name) {
query.name = name;
}
//依据 query 对象查询文章
collection.find(query).sort({
time: -1
}).toArray(function (err, docs) {
mongodb.close();
if (err) {
return callback(err);//失败!返回 err
}
callback(null, docs);//成功!以数组形式返回查询的结果
});
});
});
};

blog/models/user.js

var mongodb = require('./db');

function User(user) {
this.name = user.name;
this.password = user.password;
this.email = user.email;
}; module.exports = User; //存储用户信息
User.prototype.save = function(callback) {
//要存入数据库的用户文档
var user = {
name: this.name,
password: this.password,
email: this.email
};
//打开数据库
mongodb.open(function (err, db) {
if (err) {
return callback(err);//错误。返回 err 信息
}
//读取 users 集合
db.collection('users', function (err, collection) {
if (err) {
mongodb.close();
return callback(err);//错误。返回 err 信息
}
//将用户数据插入 users 集合
collection.insert(user, {
safe: true
},
function (err, user) {
mongodb.close();
if (err) {
return callback(err);//错误,返回 err 信息
}
callback(null, user[0]);//成功! err 为 null,并返回存储后的用户文档
});
});
});
}; //读取用户信息
User.get = function(name, callback) {
//打开数据库
mongodb.open(function (err, db) {
if (err) {
return callback(err);//错误,返回 err 信息
}
//读取 users 集合
db.collection('users', function (err, collection) {
if (err) {
mongodb.close();
return callback(err);//错误。返回 err 信息
}
//查找username(name键)值为 name 一个文档
collection.findOne({
name: name
},
function (err, user) {
mongodb.close();
if (err) {
return callback(err);//失败! 返回 err 信息
}
callback(null, user);//成功! 返回查询的用户信息
});
});
});
};

blog/public/

blog/public/stylesheets/style.css

/* inspired by http://yihui.name/cn/ */
*{padding:0;margin:0;}
body{width:600px;margin:2em auto;padding:0 2em;font-size:14px;font-family:"Microsoft YaHei";}
p{line-height:24px;margin:1em 0;}
header{padding:.5em 0;border-bottom:1px solid #cccccc;}
nav{position:fixed;left:12em;font-family:"Microsoft YaHei";font-size:1.1em;text-transform:uppercase;width:9em;text-align:right;}
nav a{display:block;text-decoration:none;padding:.7em 1em;color:#000000;}
nav a:hover{background-color:#ff0000;color:#f9f9f9;-webkit-transition:color .2s linear;}
article{font-size:16px;padding-top:.5em;}
article a{color:#dd0000;text-decoration:none;}
article a:hover{color:#333333;text-decoration:underline;}
.info{font-size:14px;}

blog/routes/

blog/routes/index.js

/*
* GET home page.
*/
var crypto = require('crypto'),
User = require('../models/user.js'),
Post=require('../models/post.js'); module.exports = function(app) {
app.get('/', function (req, res) {
Post.get(null, function (err, posts) {
if (err) {
posts = [];
}
res.render('index', {
title: '主页',
user: req.session.user,
posts: posts,
success: req.flash('success').toString(),
error: req.flash('error').toString()
});
});
}); app.get('/reg', checkNotLogin);
app.get('/reg', function (req, res) {
res.render('reg', {
title: '注冊',
user: req.session.user,
success: req.flash('success').toString(),
error: req.flash('error').toString()
});
}); app.post('/reg', checkNotLogin);
app.post('/reg', function (req, res) {
var name = req.body.name,
password = req.body.password,
password_re = req.body['password-repeat'];
//检验用户两次输入的密码是否一致
if (password_re != password) {
req.flash('error', '两次输入的密码不一致!');
return res.redirect('/reg');//返回注冊页
}
//生成密码的 md5 值
var md5 = crypto.createHash('md5'),
password = md5.update(req.body.password).digest('hex');
var newUser = new User({
name: name,
password: password,
email: req.body.email
});
//检查username是否已经存在
User.get(newUser.name, function (err, user) {
if (user) {
req.flash('error', '用户已存在!');
return res.redirect('/reg');//返回注冊页
}
//假设不存在则新增用户
newUser.save(function (err, user) {
if (err) {
req.flash('error', err);
return res.redirect('/reg');//注冊失败返回主冊页
}
req.session.user = user;//用户信息存入 session
req.flash('success', '注冊成功!');
res.redirect('/');//注冊成功后返回主页
});
});
}); app.get('/login', checkNotLogin);
app.get('/login', function (req, res) {
res.render('login', {
title: '登录',
user: req.session.user,
success: req.flash('success').toString(),
error: req.flash('error').toString()});
}); app.post('/login', checkNotLogin);
app.post('/login', function (req, res) {
//生成密码的 md5 值
var md5 = crypto.createHash('md5'),
password = md5.update(req.body.password).digest('hex');
//检查用户是否存在
User.get(req.body.name, function (err, user) {
if (!user) {
req.flash('error', '用户不存在!');
return res.redirect('/login');//用户不存在则跳转到登录页
}
//检查密码是否一致
if (user.password != password) {
req.flash('error', '密码错误!');
return res.redirect('/login');//密码错误则跳转到登录页
}
//username密码都匹配后,将用户信息存入 session
req.session.user = user;
req.flash('success', '登陆成功!');
res.redirect('/');//登陆成功后跳转到主页
});
}); app.get('/post', checkLogin);
app.get('/post', function (req, res) {
res.render('post', {
title: '发表' ,
user: req.session.user,
success: req.flash('success').toString(),
error: req.flash('error').toString()}); console.log("222");
}); app.post('/post', checkLogin);
app.post('/post', function (req, res) { var currentUser = req.session.user,
post = new Post(currentUser.name, req.body.title, req.body.post);
post.save(function (err) {
if (err) {
req.flash('error', err);
return res.redirect('/');
}
req.flash('success', '公布成功!');
res.redirect('/');//发表成功跳转到主页
});
}); app.get('/logout', checkLogin);
app.get('/logout', function (req, res) {
req.session.user = null;
req.flash('success', '登出成功!');
res.redirect('/');//登出成功后跳转到主页
}); function checkLogin(req, res, next) {
if (!req.session.user) {
req.flash('error', '未登录!');
res.redirect('/login');
}
next();
} function checkNotLogin(req, res, next) {
if (req.session.user) {
req.flash('error', '已登录!');
res.redirect('back');
}
next();
}
};

blog/views/

blog/views/header.ejs

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Blog</title>
<link rel="stylesheet" href="/stylesheets/style.css">
</head>
<body> <header>
<h1><%= title %></h1>
</header> <nav>
<span><a title="主页" href="/">home</a></span>
<% if (user) { %>
<span><a title="发表" href="/post">post</a></span>
<span><a title="登出" href="/logout">logout</a></span>
<% } else { %>
<span><a title="登录" href="/login">login</a></span>
<span><a title="注冊" href="/reg">register</a></span>
<% } %>
</nav> <article> <% if (success) { %>
<div><%= success %></div>
<% } %>
<% if (error) { %>
<div><%= error %> </div>
<% } %>

blog/views/footer.ejs

</article>
</body>
</html>

blog/views/index.ejs

<%- include header %>
<% posts.forEach(function (post, index) { %>
<p><h2><a href="#"><%= post.title %></a></h2></p>
<p class="info">
作者:<a href="#"><%= post.name %></a> |
日期:<%= post.time.minute %>
</p>
<p><%- post.post %></p>
<% }) %>
<%- include footer %>

blog/views/reg.ejs

<%- include header %>
<form method="post" url='/reg'>
username: <input type="text" name="name"/><br />
密码: <input type="password" name="password"/><br />
确认密码:<input type="password" name="password-repeat"/><br />
邮箱: <input type="email" name="email"/><br />
<input type="submit" value="注冊"/>
</form>
<%- include footer %>

blog/views/login.ejs

<%- include header %>
<form method="post">
username:<input type="text" name="name"/><br />
密码: <input type="password" name="password"/><br />
<input type="submit" value="登录"/>
</form>
<%- include footer %>

blog/views/post.ejs

<%- include header %>
<form method="post" url='/post'>
TITLE:<br />
<input type="text" name="title" /><br />
DETAIL:<br />
<textarea name="post" rows="20" cols="100"></textarea><br />
<input type="submit" value="POST" />
</form>
<%- include footer %>

关于这个疑问

找到答案了

router is executed without session executed while session is used in router , i think

Node.js 博客实例(一)简单博客的更多相关文章

  1. Node.js 从零开发 web server博客项目[express重构博客项目]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  2. Node.js 从零开发 web server博客项目[安全]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  3. Node.js 从零开发 web server博客项目[数据存储]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  4. Node.js 从零开发 web server博客项目[koa2重构博客项目]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  5. Node.js 从零开发 web server博客项目[日志]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  6. Node.js 从零开发 web server博客项目[登录]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  7. Node.js 从零开发 web server博客项目[接口]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  8. Node.js 从零开发 web server博客项目[项目介绍]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  9. 玩转Node.js(四)-搭建简单的聊天室

    玩转Node.js(四)-搭建简单的聊天室 Nodejs好久没有跟进了,最近想用它搞一个聊天室,然后便偶遇了socket.io这个东东,说是可以用它来简单的实现实时双向的基于事件的通讯机制.我便看了一 ...

  10. 用node.js从零开始去写一个简单的爬虫

    如果你不会Python语言,正好又是一个node.js小白,看完这篇文章之后,一定会觉得受益匪浅,感受到自己又新get到了一门技能,如何用node.js从零开始去写一个简单的爬虫,十分钟时间就能搞定, ...

随机推荐

  1. UML基本架构建模--获取类

     Getting Started 開始 Modeling a system involves identifying the things that are important to your p ...

  2. Hdu 4280 Island Transport(最大流)

    Island Transport Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  3. MongoDB初探系列之四:MongoDB与Java共舞

    因为版本号不同,可能API也有所不同.本次学习用的是3.0版本号. 1.使用的mongodb的jdbc驱动版本号为:mongo-java-driver-3.0.0.jar 2.本节仅仅是简介JDBC操 ...

  4. JDBC整理

    JDBC提供了独立于数据库的统一Api,用以执行SQL命令.JDBC API由以下常用的接口和类组成: DriverManagement:用于管理JDBC驱动的服务类,程序中使用该类的主要功能是获取C ...

  5. Java做一个时间的程序,为什么要除以1000*60*60*24啊。这个数字是什么意思啊。

    1000耗秒(1秒),60秒(1分),60分(1小时),24小时(1天)

  6. 更改python字符编码以便使用UTF-8的编码url路径

    url编码分两种, 一种是unicode, 另一种是gb2312, 今天遇到的一个网站是要将字符编码按照gb2312来编码,用来得到一个先填写blanks后再返回页面的数据,废话少说,需要做的就是先查 ...

  7. Spring mvc 实现jsonp和json数据类型

            在使用springmvc开发rest接口的时候很方便,可以直接使用@ResponseBody注解,直接加在springmvc的控制器类的方法上,springmvc会直接为我们将返回的对 ...

  8. 50个极好的bootstrap 后台框架主题下载

    50个极好的bootstrap 后台框架主题下载 http://sudasuta.com/bootstrap-admin-templates.html 越来越多的设计师和前端工程师开始用bootstr ...

  9. Fine-tuning CaffeNet for Style Recognition on “Flickr Style” Data 数据下载遇到的问题

    (下载的时候没有提示 不知道是正在下 还是出现错误 卡着了)..一直没有反应 下载前要以管理员身份运行 sudo su 再 python examples/finetune_flickr_style/ ...

  10. mac下安装postgreSql

    在 mac 下,可以利用 homebrew 直接安装 PostgreSQL: 1 brew install postgresql -v 稍等片刻,PostgreSQL 就安装完成.接下来就是初始数据库 ...