2013-01-02 38 views
1

我搜索並發現很多類似的問題,會話變量被設置爲undefined,但沒有一個我發現的答案似乎適用。會話變量沒有存儲在node.js中

我有我的路由器文件這一功能:

exports.loginHandler = function(req, res){ 
    username = req.body.username; 
    password = req.body.password; 
    readAccount(username, function(acct){ 
     if (acct.password = password){ 
      req.session.username = username; 
      console.log(username+' logged in'+' pass: '+acct.password); 
     }; 
    }); 
    res.redirect('/'); 
}; 

的console.log執行得很好,雙方的用戶名和acct.password有適當的值。但是,req.session.username最終會被設置爲undefined。

這裏的readAccount功能:

readAccount = function(user, callback){ 
    AM.login(user, function(acct){ 
     callback(acct); 
    }); 
}; 

而這裏的AM.login:

exports.login = function(user, callback){ 
    accounts.findOne({username: user}, function(err, result){ 
    if (err) throw err; 
    callback(result); 
    }) 
} 

我猜會話變量不能的條件下進行設置,因爲這種類型的錯誤沒有按」 t似乎不常見。

+0

你真的爲你的應用程序設置了會話狀態存儲嗎? AFAIK它不會出爐。 –

+0

它確實用快遞出爐,或者至少它爲我做了。問題是res.redirect在變量被分配之前正在執行。 – user1816679

+0

啊,好吧,我以某種方式錯過了快遞標籤。 –

回答

5

問題在於,您在重定向後會結束響應並保存會話,然後再設置session.username屬性。這是因爲readAccount(通過accounts.findOne)是異步的,在調用res.redirect()之前不會完成。

您可以通過移動res.redirect()readAccount回調確保其執行順序:

exports.loginHandler = function(req, res){ 
    username = req.body.username; 
    password = req.body.password; 

    readAccount(username, function(acct){ 
     if (acct.password = password){ 
      req.session.username = username; 
      console.log(username+' logged in'+' pass: '+acct.password); 
     }; 

     res.redirect('/'); 
    }); 
}; 

同時,應注意與throw「在異步操作荷蘭國際集團的錯誤。該回調將具有與啓動功能不同的調用堆棧(例如readAccount),這使得catch錯誤變得困難。這就是爲什麼許多用於Node的API將錯誤作爲參數傳遞的原因。

+0

謝謝!完美工作。 – user1816679

+0

如何在其他地方訪問這個變量? – Saani

0

其簡單易行的方法是在發送迴應前寫下行。

res.locals.session = req.session;

並且您的會話將保存該變量的值。