標籤:疑問 r.js fixed develop code input mode 源碼 routes
原教程 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" >
登入成功:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZG9uZ3NoYW9zaHVhaQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" >
發表部落格:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZG9uZ3NoYW9zaHVhaQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" >
發表成功:
源碼: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 environmentsapp.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 onlyif ('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;//使用者資訊存入 sessionreq.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密碼都匹配後,將使用者資訊存入 sessionreq.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 部落格執行個體(一)簡單部落格