use*_*679 1 session node.js express
我搜索并发现很多类似的问题,会话变量设置为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('/');
};
Run Code Online (Sandbox Code Playgroud)
console.log执行得很好,username和acct.password都有适当的值.但是,req.session.username最终被设置为undefined.
这是readAccount函数:
readAccount = function(user, callback){
AM.login(user, function(acct){
callback(acct);
});
};
Run Code Online (Sandbox Code Playgroud)
这是AM.login:
exports.login = function(user, callback){
accounts.findOne({username: user}, function(err, result){
if (err) throw err;
callback(result);
})
}
Run Code Online (Sandbox Code Playgroud)
我猜测会话变量不能在条件下设置,因为这种类型的错误似乎并不常见.
问题是您在设置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('/');
});
};
Run Code Online (Sandbox Code Playgroud)
另外,请注意throw异步操作中的错误.回调将具有与启动函数(例如readAccount)不同的调用堆栈,这使得catch错误变得困难.这就是为什么许多Node for Node将错误作为参数传递的原因.