【问题标题】:Session not storing in Express for Node.js会话未存储在 Express for Node.js 中
【发布时间】:2012-06-09 09:28:55
【问题描述】:

我有以下基本上从登录表单作用于帖子的路线。问题是当登录成功时(找到成员并且密码匹配),成员._id没有存储在会话中。

我的路线:

app.post('/signin', function(req, res) {
    Member.findOne({username: req.body.username}, function(error, member) {
        var matchPassword = crypto.createHmac('sha1', member.salt).update(req.body.password).digest('hex');
        if(member.password == matchPassword) {
            req.session.member_id = member._id;
            res.redirect('/' + member.username);
        }
    });
    res.redirect('/');
});

触发此路由时,我在控制台中收到以下错误:

node.js:134
        throw e; // process.nextTick error, or 'error' event on first tick
        ^
Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:527:11)
    at ServerResponse.setHeader (/Users/admin/Node Projects/sandboxProject/node_modules/express/node_modules/connect/lib/patch.js:62:20)
    at ServerResponse.header (/Users/admin/Node Projects/sandboxProject/node_modules/express/lib/response.js:280:8)
    at ServerResponse.redirect (/Users/admin/Node Projects/sandboxProject/node_modules/express/lib/response.js:413:10)
    at Promise.<anonymous> (/Users/admin/Node Projects/sandboxProject/app.js:109:8)
    at Promise.<anonymous> (/Users/admin/Node Projects/sandboxProject/node_modules/mongoose/lib/promise.js:120:8)
    at Promise.<anonymous> (events.js:64:17)
    at Promise.emit (/Users/admin/Node Projects/sandboxProject/node_modules/mongoose/lib/promise.js:59:38)
    at Promise.complete (/Users/admin/Node Projects/sandboxProject/node_modules/mongoose/lib/promise.js:70:20)
    at /Users/admin/Node Projects/sandboxProject/node_modules/mongoose/lib/query.js:1087:15

它似乎不喜欢“res.redirect('/' + member.username);”在“req.session.member_id = member._id;”之后。这是因为它所在的 Mongoose findOne 回调的异步特性吗?我已尝试从回调中删除 res.redirect,但未存储会话数据,当我将其保留在那里时,出现“标头已发送”错误。

我的配置:

app.configure(function(){
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade');
    app.use(express.cookieParser());
    app.use(express.session({ secret: "blahblah" }));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
});

【问题讨论】:

  • 已经解决了这个问题 - 原来它很简单,需要一点常识!由于来自 Mongoose 的回调是异步的,并且在“res.redirect('/');”之后触发了会话存储。在我以前的损坏版本的路线中。您需要做的就是处理回调内部的失败并删除“res.redirect('/');”从路由回调结束。糟糕!
  • 如果以下解决方案有效,您能否选择一个作为正确答案,以帮助其他有同样问题的人?

标签: node.js express


【解决方案1】:

我遇到了类似的问题。虽然我的问题是当我从会话中删除某些内容时,例如delete req.session.user,在重新加载和节点应用程序重新启动后它仍然存在。它只会在req.session.destroy() 之后消失。

我查看了Node的会话middleware docs,发现他们有一个Session#save()方法。所以我在会话对象操作之后做了req.session.save(),它确实解决了我的问题。试试看它是否能解决你的问题。

【讨论】:

  • 尽管这个答案为我指明了正确的方向,但我会明确指出 req.session.save() 是一个以回调为参数的异步函数。所以任何依赖于保存数据的东西都应该在回调中执行。当仅使用内存存储进行开发并且动作“及时”发生时,这通常并不明显。
【解决方案2】:

问题在于Member.findOne 是异步的。在其回调执行时,res.redirect('/') 已经执行,它设置了适当的 HTTP 响应标头。您不能通过 HTTP 规则发送两次标头,因此会出现错误 Can't set headers after they are sent.

您可能希望将 redirect('/') 移动到密码匹配的 else 块中。

【讨论】:

    【解决方案3】:

    我遇到了类似的问题。 但我当时的问题是:

    request.session.user = 用户;

    我通过debug发现,注释掉这一行的时候,没有出现这个错误:

    // request.session.user = user;

    这是我的问题: express 4.x session-mongoose Can't set headers after they are sent(Been resolved)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-17
      • 2013-06-20
      • 2012-04-28
      相关资源
      最近更新 更多