《Nodejs开发指南》中遇到的问题2

来源:互联网 发布:logo设计软件绿色版 编辑:程序博客网 时间:2024/04/27 13:27

  终于把书中的例子用新版本的框架和包开发完成了,还是学到了不少。由于代码多是在原有代码上修改,编码能力没什么提高,但分析问题的水平提高了,也对node和express有了一个初步的了解。最终,发微博部分出现的问题很低级,是posts.js这个文件的里变量名写错了一个,但报错并没有报posts这个文件出错,而是说title is not defined,这也导致我的注意力一直放在layout.esj和index.js这两个文件上,这样的报错实在太坑爹了。最终,我将layout.ejs中的<%= title %>改为<%= locals.title %>,让title不需传入,直接使用全局变量。从而发现了问题究竟在哪。

  此外,<%- partial('say') %>中partial已经不再受支持,改为了include,所以例子中出现partial的地方一律这样改

<%- include('say'); %>。样式问题,书中使用bootstrap来进行布局和装饰,新版中大部分class名已经改变,这里我们只需根据bootstrap官网上的内容,对书中的几个模板文件进行相应修改即可。

下面附上全部js代码:

//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 settings = require('./settings');
var routes = require('./routes/index');
var users = require('./routes/users');
var flash = require('connect-flash');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
var partials = require('express-partials');
app.use(partials());
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(flash());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({
  secret: settings.cookieSecret,
  name: 'testapp',
  cookie: {maxAge: 80000 },
  resave: false,
  saveUninitialized: true,
  store: new MongoStore({
  host:'localhost',
  port:27017,
  db: settings.db,
  url:'mongodb://localhost/microblog'
  })
}));
app.use(function(req, res, next){
  console.log("app.usr 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(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/post',routes);
app.use('/reg',routes);
app.use('/login',routes);
app.use('/logout',routes);
app.use('/u/:users',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;
app.listen(3000);




//user.js

MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/microblog';
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,
};
MongoClient.connect(url,function(err,db) {
if (err) {
return callback(err);
}
db.collection('users',function(err,collection) {
if(err){
db.close();
return callback(err);
}
collection.ensureIndex('name',{unique:true});
collection.insert(user,{safe:true},function(err,user) {
db.close();
callback(err,user);
});
});
});
};
User.get = function get(username, callback) {
MongoClient.connect(url,function(err, db) {
if (err) {
return callback(err);
}
// 读取 users 集合
db.collection('users', function(err, collection) {
if (err) {
db.close();
return callback(err);
}
// 查找 name 属性为 username 的文档
collection.findOne({name: username}, function(err, doc) {
db.close();
if (doc) {
// 封装文档为 User 对象
var user = new User(doc);
callback(err, user);
} else {
callback(err, null);
}
});
});
});
};






//index.js

var express = require('express');
var router = express.Router();
var crypto = require('crypto');
var User = require('../node_modules/user.js');
var Post = require('../node_modules/post.js');
/* GET home page. */
router.get('/', function(req, res, next) {
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, next) {
res.render('reg',{ title: '用户注册' });
});
router.post('/reg', checkNotLogin);
router.post('/reg',function(req, res, next) {
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) {
res.render('login', {title: '用户登入'});
});
router.post('/login', checkNotLogin);
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('/');
});
});
router.get('/logout', checkLogin);
router.get('/logout',function(req, res, next) {
req.session.user = null;
req.flash('success', '登出成功');
res.redirect('/');
});
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('/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('/');
}
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;





//post.js

MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/microblog';
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 = {
user: this.user,
post: this.post,
time: this.time,
};
MongoClient.connect(url, 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');
// 写入 post 文档
collection.insert(post, {safe: true}, function(err, post) {
db.close();
callback(err, post);
});
});
});
};
Post.get = function get(username, callback) {
MongoClient.connect(url, function(err, db) {
if (err) {
return callback(err);
}
// 读取 posts 集合
db.collection('posts', function(err, collection) {
if (err) {
db.close();
return callback(err);
}
var query = {};
if (username) {
query.user = username;
}
collection.find(query).sort({time: -1}).toArray(function(err, docs) {
db.close();
if (err) {
callback(err, null);
}
// 封装 posts 为 Post 对象
var posts = [];
docs.forEach(function(doc, index) {
var post = new Post(doc.user, doc.post, doc.time);
posts.push(post);
});
callback(null, posts);
});
});
});
};





//package.json

{
  "name": "microblog",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "body-parser": "~1.15.1",
    "connect-flash": "^0.1.1",
    "connect-mongo": "^1.3.2",
    "cookie-parser": "~1.4.3",
    "debug": "~2.2.0",
    "ejs": "~2.4.1",
    "express": "~4.13.4",
    "express-partials": "^0.3.0",
    "express-session": "~1.0.4",
    "kerberos": "~0.0.17",
    "mongodb": "^2.2.8",
    "morgan": "~1.7.0",
    "serve-favicon": "~2.3.0"
  }
}

1 0