节点会话未正确保存

时间:2016-12-29 22:16:11

标签: javascript node.js mongodb session

我在节点会话中看到了一些非常奇怪的东西。我使用express-sessionconnect-mongo来保存会话。

我的会话设置如下(所有请求都通过https):

var session = require('express-session');
var MongoStore = require('connect-mongo/es5')(session);

var sess = {};

app.use(session({
    secret: 'xxxx',
    saveUninitialized: false,
    store: new MongoStore({
        mongooseConnection: mongoose.connection,
        ttl: 60 * 30 // haf hour
    }),
    cookie: { secure: true }
}));

我有一个使用节点画布创建图像的路径:

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

    sess = req.session;

    console.log('in canvas and sess is ', sess);

    // create image stuff
});

在应用程序的其他地方,您可以设置背景颜色等内容。然后,我有一条清除这些的路线:

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

    sess = req.session;

    if (sess.colors) {
        delete sess.colors;
    }

    sess.save(function(err) {
        console.log('saved sess is now ', sess);
        // session saved
        helper.sendJsonResponse(req, res, 200, {});
    })
});

helper.sendJsonResponse()只需使用 200 HTTP代码和空身回复。

您可以看到我使用session.save()的回调,因为我只想在我知道会话编辑和保存时回复请求。

但是,这并不总是有效。如果我在会话中设置颜色,然后清除它们(通过调用' api / clear'路线),然后调用路线创建图像(通过调用' api / canvas' route ),关于' api / canvas'的会议路线会议有时仍然会设置颜色。

只有当我快速完成时才会出现这种情况。如果我等待几秒钟,就会清除颜色,以便' api / canvas'路线。

注意:我不允许同时调用这些路由 - 我使用promises并在UI中有一个微调器,覆盖整个屏幕,直到请求完全完成。

当发生这种情况时,日志看起来像:

saved sess is now  { cookie: 
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true },
  canvasHeight: 500,
  canvasWidth: 591 
}

当我向' api / canvas':

提出请求时
in canvas and sess is  { cookie: 
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true },
  canvasHeight: 500,
  canvasWidth: 591,
  colors: 
   { 
      color1: 'red',
      color2: 'green'
    } 
}

所以你可以看到,颜色属性仍然设置。大约50%的时间都会发生这种情况。剩下的时间,在第二个请求中,colors属性已被删除。

可能出现什么问题?我误解了会议的运作方式吗?

修改

这变得越来越奇怪。如果我在UI中链接调用,则称为' api / clear'然后在Promise then()方法中调用' api / canvas'路线,它总是有效。如果我打电话单独提出请求,结果是完全随机的 - 有时会话会更新,有时候会赢。

我检查了req.sessionID,并且对于不同的请求它始终是相同的。

修改 使用regenerate method可以正常使用,但并不理想,因为我在会话中丢失了所有内容。

1 个答案:

答案 0 :(得分:0)

删除操作符仅删除引用,而不删除对象本身。如果它确实删除了对象本身,那么其他剩余的引用将是悬空的,就像C ++删除一样。 (并且访问其中一个会导致崩溃。要使它们全部转为null将意味着在删除或为每个对象额外的内存时有额外的工作。)

由于Javascript是垃圾收集的,因此您无需自行删除对象 - 当无法再引用它们时,它们将被删除。

如果您已完成对象的删除,则删除对象的引用会很有用,因为这会为垃圾回收器提供有关可以回收的内容的更多信息。如果对大对象的引用仍然存在,这可能导致它无法回收 - 即使程序的其余部分实际上没有使用该对象。

<强>参考: http://jennifermann.ghost.io/deleting-objects-in-javascript/

希望这有帮助。