在当前项目(一种商店系统)中,我将node.js与 expressJS 和 connect-mongo 一起用作会话存储。在客户端,我在启动时使用单个请求来创建新会话,然后向node.js服务器发送多个并行请求。 因为这些并行请求会更改会话,所以这些更改似乎会相互覆盖,当然,它们会更改会话的不同对象。
示例(所有3个请求同时开始):
req.session.productHist['abc']
req.session.productHist['def']
因为请求C在请求A和B之后完成,但在它们完成之前开始,它似乎用请求C开始时保持的值覆盖session.productHist
(null)。
我该如何解决这个问题?
更新
一些带控制台输出的示例代码:
var url = require('url'),
express = require('express'),
MongoStore = require('connect-mongo');
var aDay = 24*60*60*1000;
var app = express.createServer();
app.configure(function(){
app.use(express.cookieParser());
app.use(express.session({
secret: "secret",
store: new MongoStore({ db: 'lmsCache' }),
maxAge: aDay
})
);
app.use(express.methodOverride()); app.use(express.bodyParser());
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
app.use(app.router);
app.use(express.logger());
});
function sendStringified(req, res, data) {
data = JSON.stringify(data);
if (req.url_query.callback) { data = req.url_query.callback + "(" + data + ");"; }
res.send(data);
}
function parseParams(req,res,next) {
req.url_query = url.parse(req.url,true).query;
next();
}
function doExpensiveStuff(req,res,next) {
console.log("######################### init start");
[...]
}
app.get('/init', parseParams, doExpensiveStuff, function(req,res) {
console.log("init: session.productHist: " + JSON.stringify(req.session.productHist));
console.log("######################### init end");
sendStringified(req,res,null);
});
app.get('/products', parseParams, function(req,res) {
console.log("######################### products "+req.url_query.category+" start");
if(!req.session.productHist[req.url_query.category])
req.session.productHist[req.url_query.category] = [];
for(var i=0;i<2;i++) {
req.session.productHist[req.url_query.category].push({ "id": new Date().toGMTString() });
}
console.log("products: session.productHist: " + JSON.stringify(req.session.productHist));
console.log("######################### products "+req.url_query.category+" end");
sendStringified(req,res,[]);
});
app.get('/newSession', parseParams, function(req,res) {
console.log("######################### newSession");
req.session.productHist = {};
sendStringified(req,res,true);
});
app.listen(8080);
time = new Date().toGMTString();
console.log('Server starting at: ' + time);
控制台日志:
服务器起始于:2011年12月15日星期四15:50:37 GMT
################### newSession
################### init start ################### products -1 start产品:session.productHist:{“ - 1”:[{“id”:“星期四,2011年12月15日15:50:40 GMT”},{“id”:“星期四,2011年12月15日15:50 :40 GMT“}]}
################### products -1 end################### init end
init:session.productHist:{}################### products -1 start
[...]产品:session.productHist:{“ - 1”:[{“id”:“星期四,2011年12月15日15:50:53 GMT”},{“id”:“星期四,2011年12月15日15:50 :53 GMT“}]}
################### products -1 end
答案 0 :(得分:3)
我想我找到了这个棘手问题的答案。
来自Express.js文档:
Properties on req.session are automatically saved on a response
简短版
当您设置会话变量(req.session.my_var = value
)时,它实际上并未保存(在那个确切的时刻),但稍后(当您发送响应时,在您的情况下,当您执行res.send
时)。这导致了你的问题。
长版
那究竟是什么意思?