《Nodejs开发指南》这本书很易懂,相比其他node书籍更适合新手看。但书中的实例使用的是express2.0版本,express如今已经更新到4x。不仅如此,书中所用的各种包的版本也非常旧,在使用新版本开发的过程中会出现各种问题。如果想去实现书中的例子,建议还是使用老版本的包和express,不然这个过程会很痛苦,因为可以查到的资料实在是太少了,而且最新版的使用说明多是全英文的。我历经千辛万苦终于把除发表微博的其他部分完成了。
我在刚开始编写这个微博实例的时候,大量的参考了另一篇博客http://www.cnblogs.com/yuanzm/p/3770986.html,这篇文章把基本上常见的问题都解决了,但由于这篇文章距今也快两年了,如果我们用最新的包进行开发,可能还会遇到别的问题,下面的内容当做是对这篇文章的一点补充。
首先说一下node中的路径问题,在node中../代表上级目录,./代表同级目录,/代表根目录,这样说很笼统,这里有一篇博客讲解了node中的路径,很明了http://blog.csdn.net/a477997/article/details/50194147,在这就不做多余的解释。
在node中,我们使用npm来管理包,package.json中存放的是依赖信息,包括包的名称和版本。当我们直接使用npm install,node会自动根据package.json中的信息为我们安装包。如果我们只想安装某个包最新版本,例如mongodb的驱动,则需这样
npm install mongodb --save 其中--save表示将信息添加进package.json。
废话到此为止,下面开始一一例举我在学习过程中遇到的坑。这些坑主要都是围绕在node中使用mongodb。
首先,我在执行npm install mongodb时各种报错,无法安装成功。网上也找不到解决办法。我仔细回想,想起书中开篇说要安装python,但是我别的包都能安装,就mongodb安装不了,这能跟python有关?于是抱着试一试的心态,我安装了python,于是,tmd这次mongodb竟然安装成功了。
我欢呼雀跃,以为问题就此解决,然而当我敲下 node app.js后,又报了新的错误。“invalid schema,expected mongodb”噩梦就此开始了。我试了网上所有的解决办法,都没用。我看了mongodb的api文档,发现书中的,包括网上的答案中的mongodb驱动都不是最新版的(废话),书中db.js这个文件就是为了新建一个数据库server,然后把它暴露出来以供使用。
//db.js
var settings = require('../settings');
var Db = require('mongodb').Db;
var Connection = require('mongodb').Connection;
var Server = require('mongodb').Server;
module.exports = new Db(settings.db, new Server(settings.host, Connection.DEFAULT_
PORT, {}))
但新版的文档中说,已经不建议使用Server,而要使用MongoClient。最终,我不使用db.js,直接将user.js文件改为如下:
//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) {//注意,这里不再是open,改为connect
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);
}
});
});
});
};
我天真地以为这次一定没问题了,但还是报了相同的错invalid schema ,expected mongodb。。。这次,根据报错信息,我看了看node_modules\mongodb\lib下的url_parser.js文件。发现报错是因为没有找到url参数,而且这个url参数应该是在session中设置的。又是版本问题,老版本中根本不需要这只这个,于是app.js中设置session的代码由
app.use(express.session({
secret: settings.cookie_secret,
store:new MongoStore({
db: settings.db
})
}));
变为
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'
})
}));
终于,数据库的问题解决了,但是当我打开页面,却提示我title is not defined等一系列错误,明明我应经把title传给layout.ejs文件了。这次,问题出现的原因是我把作为动态视图助手的那段代码放的太靠后,它应放在app.js中路由控制的代码之前,像这样:
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);
到现在,书中例子发微博之前的这部分就没什么问题了。