1. 程式人生 > >NodeJS開發指南——mongoDB、Session

NodeJS開發指南——mongoDB、Session

記錄一下這兩天用nodeJS搭建一個部落格系統遇到的坑;

關於mongoDB

資料庫的連線

db.js

var settings = require('../settings');
var mongo = require('mongodb');

var Server=mongo.Server;
var Db=mongo.Db;
var server = new Server('localhost', 27017, {auto_reconnect: true});
var db = new Db(settings.db, server);

var Connection = require
('mongodb').Connection; module.exports=db;

資料庫的查詢

User.get = function(username,callback) {
    // body...
    mongodb.open(function(err, db) {
        if (!err) {
            console.log("We are connected");
            db.collection('users', function(err, collection) {
                collection.find().toArray(function
(error, users) {
console.log(users); }); // collection.find({ a: 1 }).toArray(function(error, bars) { console.log(bars); }); collection.findOne({ name:username }, function(error, doc) { console.log('username'+doc); if
(doc){ var user = new User(doc); callback(err, user); } }); }); } }); };

1 、Connection strategy not found

app.use(express.session({
secret: settings.cookieSecret, 
store: new MongoStore({
          db: settings.db
        })
}));

改成

app.use(session({
    secret: settings.cookieSecret,
    store: new MongoStore({
        url: 'mongodb://localhost/microblog',
        autoRemove: 'native'
    })
}));

2、throw new Error(‘no hostname or hostnames provided in connection string’);
需要在mongoDB裡面建立一個數據庫
這裡寫圖片描述

3、server instance in invalid state undefined
原因第一次使用了資料庫之後未正常關閉

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

function User(user) {
    this.name = user.name;
    this.password = user.password;
    this.email = user.email;
}
module.exports = User;

User.prototype.save = function(callback) {
    // body...
    var user = {
        name: this.name,
        password: this.password,
        email: this.email
    }
    console.log('save' + user.name)
    mongodb.open(function(err, db) {
        if (err) {
            console.log('User open err')
            return callback(err);
        }
        db.collection('users', function(err, collection) {
            console.log(err)

            if (err) {
                mongodb.close();
                return callback(err);
            }
            console.log('User open success')

            //為name屬性新增索引
            var doc1 = user;
            collection.ensureIndex('name', { unique: true });
            //寫入user文件
            collection.insert(doc1, { safe: true }, function(err, result) {
                mongodb.close();
                callback(err, user);
            });

        })
    })
};
User.get = function(username, callback) {
    // body...
    mongodb.open(function(err, db) {
        if (!err) {
            console.log("We are connected");
            db.collection('users', function(err, collection) {
                collection.find().toArray(function(error, users) {
                    console.log(users);
                });
                // collection.find({ a: 1 }).toArray(function(error, bars) { console.log(bars); });
                collection.findOne({ name: username }, function(error, doc) {
                    console.log('username' + doc);
                    if (doc) {
                        var user = new User(doc);
                        callback(err, user);
                    }
                    mongodb.close(); //這裡之前忘記寫了
                    callback(err, user);
                });
            });
        }
    });
};

關於處理POST請求

1、註冊頁面的寫法
reg.ejs

<%- include header %>
<form role="form" method="post">
  <div class="form-group">
    <label for="username1">username</label>
    <input name="username" type="text" class="form-control" id="username" placeholder="Enter username">
  </div>
  <div class="form-group">
    <label for="Email1">Email</label>
    <input name="email" type="email" class="form-control" id="Email1" placeholder="Enter email">
  </div>
  <div class="form-group">
    <label for="Password1">Password</label>
    <input name="password" type="password" class="form-control" id="Password1" placeholder="Password">
  </div>

  <button type="submit" class="btn btn-default">Submit</button>
</form>
<%- include footer %>

生成的介面是這樣的。

這裡寫圖片描述

一旦填好資訊之後,可以看到提交的username、email和password,但是我們後臺並沒有對這個請求做任何處理,下面我們來寫一下。
這裡寫圖片描述

這裡寫程式碼片

req.flash 是 Express 提供的一個奇妙的工具,通過它儲存的變數只會在使用者當前 和下一次的請求中被訪問,之後會被清除,通過它我們可以很方便地實現頁面的通知和錯誤資訊顯示功能。
User 是我們設計的使用者物件,在後面我們會詳細介紹,這裡先假設它的介面都是可
用的,使用前需要通過 var User = require(‘../models/user.js’) 引用。
通過 req.session.user = newUser 向會話物件寫入了當前使用者的資訊,在後面 我們會通過它判斷使用者是否已經登入。

動態檢視

1、app.dynamicHelpers({TypeError: Object function (req, res, next)

原因是新版本的Express已經不支援dynamicHelpers方法了。可以用locals來替代。

app.use(function(req, res, next) {
    res.locals.user = req.session.user;

    var err = req.flash('error');
    var success = req.flash('success');

    res.locals.error = err.length ? err : null;
    res.locals.success = success.length ? success : null;

    next();
});

2、user is not defined
以上程式碼一定要放在指定路由的語句之前,不然頁面中訪問user、error、success變數會出錯,提示:user is not defined。

Session儲存

在登入過程中識別使用者是一個很重要的點。
《nodeJs開發指南》這本書裡 面用的方法不能用了,查了一下,目前儲存session的方法是用express-session,和MongoStore,就是下面的兩個module

const session = require('express-session');
const MongoStore = require('connect-mongo')(session);

然後使用方法如下

// Cookie 解析的中介軟體
app.use(cookieParser());
// 提供會話支援
app.use(session({
    secret: settings.cookieSecret,
    store: new MongoStore({
        url: 'mongodb://localhost/' + settings.db,
        autoRemove: 'native'
    })
}));

這樣在每一個路由請求的時候,我們都能獲取session

如app.js

/* GET home page. */
router.get('/', function(req, res, next) {
    // if(user);
    console.log("index router:"+req.session.user)
    console.dir(req.session)
    res.render('index', { title: 'Express' });
});