繁体   English   中英

将用户保存在cookie中(已发送标头)

[英]Saving user in cookie (headers already sent)

我正在使用Express和socket.io在NodeJS中创建一个多人游戏。 大多数后端都在工作,现在我正在尝试创建前端。

真的很难尝试做以下事情:

玩家第一次打开网站>在数据库中创建一个玩家并记住玩家。 当玩家再次来到时,我们应该读取cookie并再次登录玩家。

到目前为止我的代码:

// app.js
app.get('/', function(req, res){

    if(!req.signedCookies.player) {

        var Player = new player();

        Player.on('playerLoaded', function(err, result) {
            if(result) {
                res.cookie('player', Player.id.toString(), { signed: true});
            }
        });

    } else {
        console.log(req.signedCookies.player);
    }

    res.render('index', { title: 'My Game' });

});

此行给出错误:发送后无法设置标头。

res.cookie('player', Player.id.toString(), { signed: true});

什么在这条线上讨厌:

Player.prototype.createPlayer = function () {
    var self = this;

    // we only need a datetime to insert
    connection.query("INSERT INTO players SET `created_at` = now()", function (err, result) {
        process.nextTick(function () {
            if(result) {
                console.log("Successfully created player no. " + result.insertId);

                self.id = result.insertId;

                self.emit('playerLoaded', false, true);
            } else {
                console.log("Trouble inserting a new player");

                self.emit('playerLoaded', true, false);
            }
        });
    });
};

然后确切的错误在这一行上讨厌:

self.emit('playerLoaded', false, true);

所以我的问题是:

  1. 在实现创建新播放器并将其保存在cookie中的目标方面,我是否至少朝着正确的方向前进? 如果没有,有人可以帮帮我吗?
  2. 如果问题1是真的,为什么会出错?

Cookie是响应标头的一部分。 必须第一次write()调用之前设置它们。 这就是错误的原因。 在第一次res.write()res.writeHead()调用之前设置cookie以修复错误。

此代码应该适合您。

// app.js
app.get('/', function(req, res){

  if(!req.signedCookies.player) {
    var Player = new Player();
    Player.on('playerLoaded', function(err, result) {
      if(result) {
        res.cookie('player', Player.id.toString(), { signed: true});
      }
      res.render('index', { title: 'My Game' });
    });

  } else {
      res.render('index', { title: 'My Game' });
      console.log(req.signedCookies.player);
  }

});

在实现创建新播放器并将其保存在cookie中的目标方面,我是否至少朝着正确的方向前进? 如果没有,有人可以帮帮我吗?

不确定你的设计。 保存对播放器的引用可能会使您很容易以不同的播放器身份登录,具体取决于您识别它们的方式。 进行某种会话管理,然后将用户会话与某个播放器链接起来可能更安全。

如果问题1是真的,为什么会出错?

因为创建一个播放器是异步的 - 你正在挂钩一个playerLoaded回调。 这意味着res.render将被立即调用,前res.cookie会-等响应主体已经写入(和头发送)您尝试设置cookie头前。

这解决了我发送的标头的初始问题。 还更改了代码以使用会话。

if(!req.session.player) {
    var Player = new player();

    Player.on('playerLoaded', function(err, result) {
        if(result) {
            req.session.player = Player;
            res.render('index', { title: 'My Game' });
        }
    });
} else {
    console.log(req.session.player);
    res.render('index', { title: 'My Game' });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM