节点会话未正确保存

Mar*_*ark 6 javascript session mongodb node.js

我看到节点会话非常奇怪.我正在使用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 }
}));
Run Code Online (Sandbox Code Playgroud)

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

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

    sess = req.session;

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

    // create image stuff
});
Run Code Online (Sandbox Code Playgroud)

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

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, {});
    })
});
Run Code Online (Sandbox Code Playgroud)

helper.sendJsonResponse()只响应200 HTTP代码和空体.

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

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

只有在我快速完成的情况下才会出现这种情况.如果我等待几秒钟,颜色将被清除为'api/canvas'路线.

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

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

saved sess is now  { cookie: 
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true },
  canvasHeight: 500,
  canvasWidth: 591 
}
Run Code Online (Sandbox Code Playgroud)

当我向'api/canvas'发出请求时:

in canvas and sess is  { cookie: 
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true },
  canvasHeight: 500,
  canvasWidth: 591,
  colors: 
   { 
      color1: 'red',
      color2: 'green'
    } 
}
Run Code Online (Sandbox Code Playgroud)

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

什么可能出错?我误解了会话的运作方式吗?

编辑

这变得越来越奇怪.如果我在UI中链接调用,即所谓的'api/clear'路径,那么在Promise then()方法中,调用'api/canvas'路径,它总是有效.如果我打电话单独发出请求,结果是完全随机的 - 有时会话会更新,有时则不会.

我检查req.sessionID过,不同的请求总是一样的.

编辑 使用重新生成方法正常工作,但不理想,因为我丢失了会话中的所有内容.

SUN*_*N K 0

删除运算符仅删除引用,而不删除对象本身。如果它确实删除了对象本身,则其他剩余引用将悬空,就像 C++ 删除一样。(访问其中之一会导致崩溃。使它们全部变为空意味着在删除时需要额外的工作或为每个对象提供额外的内存。)

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

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

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

希望这可以帮助。