我搜索并发现很多类似的问题,会话变量设置为undefined,但我找到的答案似乎都没有适用。
我在路由器文件中有这个功能:
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执行得很好,username和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);
})
}
我猜测会话变量不能在条件下设置,因为这种类型的错误似乎并不常见。
答案 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 for Node将错误作为参数传递的原因。
答案 1 :(得分:0)
简短的方法是在发送响应之前写下行。
res.locals.session = req.session;
并且您的会话将保存变量的值。