1

我搜索并发现了很多将会话变量设置为未定义的类似问题,但我找到的答案似乎都不适用。

我的路由器文件中有这个功能:

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 最终被设置为未定义。

这是 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);
    })
}

我猜会话变量不能在条件下设置,因为这种类型的错误似乎并不罕见。

4

2 回答 2

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异步操作中的 'ing 错误。回调将具有与起始函数不同的调用堆栈(例如readAccount),这使得catch错误变得困难。这就是为什么许多 Node API 将错误作为参数传递的原因。

于 2013-01-02T21:37:31.190 回答
0

其简短而简单的方法是在发送响应之前编写以下行。

res.locals.session = req.session;

并且您的会话将保存变量的值。

于 2017-06-23T06:35:04.120 回答