Javascript Node.js&;快速会话问题
我在会话中遇到问题,有时我刚刚设置的会话变量 在下一页请求中未定义。我通常要经历这个过程 再次,以正确设置变量 我可以确认我没有试图将会话变量设置为未定义;它们有合法的价值 在我的应用程序中,用户从/twitter/connect/移动到/twitter/callback/。前者从twitter检索一些oauth数据,后者将用户登录到twitter /twitter/connect/很简单:Javascript Node.js&;快速会话问题,javascript,node.js,Javascript,Node.js,我在会话中遇到问题,有时我刚刚设置的会话变量 在下一页请求中未定义。我通常要经历这个过程 再次,以正确设置变量 我可以确认我没有试图将会话变量设置为未定义;它们有合法的价值 在我的应用程序中,用户从/twitter/connect/移动到/twitter/callback/。前者从twitter检索一些oauth数据,后者将用户登录到twitter /twitter/connect/很简单: app.get('/twitter/connect/?', function(req, res){
app.get('/twitter/connect/?', function(req, res){
consumer().getOAuthRequestToken(function(error, oauthToken, oauthTokenSecret, results){
if (error){
// error handling here
} else {
req.session.oauthRequestToken = oauthToken;
req.session.oauthRequestTokenSecret = oauthTokenSecret;
// if I console.log the two session variables above
// they have the proper values.
res.redirect("https://twitter.com/oauth/authorize?oauth_token="+req.session.oauthRequestToken);
}
});
});
之后,twitter将它们发送回/twitter/callback/:
app.get('/twitter/callback/?', function(req, res){
console.log(req.session.oauthRequestToken);
console.log(req.session.oauthRequestTokenSecret);
// more often than not, the two variables above are
// undefined. but not always. usually on the first
// pass, never on the second.
});
我不知道发生了什么,我可以确认会话变量设置正确,它们只是在页面请求之间没有保存它们的值,只是第一次
以下是我创建服务器的方式:
app.configure('development', function(){
app.use(express.cookieParser());
app.use(express.session({ secret:'yodawgyo' }));
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
app.use(express.logger());
app.use(express.static(__dirname + '/public'));
app.set('view engine', 'ejs');
app.set('view options', {
open: '{{',
close: '}}'
});
});
我现在只有一个开发环境。我已经预装了节点0.5.0,但是在0.4.1上也看到了这个问题。我使用的是express 2.3.2
非常感谢任何帮助。在Connect的会话中,任何处理程序都可以将
请求会话设置为任何值。当处理程序调用end()
时,Connect将存储该值。如果飞行中同时有多个请求,这是危险的;当它们完成时,一个会话值将冲击另一个会话值。这是使用如此简单(或直接查看)的结果,它不支持以原子方式获取和设置会话属性
解决方法是尽量为会话中间件提供尽可能少的请求。以下是一些提示:
将express.static
处理程序置于会话中间件之上
如果无法向上移动一些不需要会话的处理程序,还可以通过说express.session.ignore.push('/individual/path')
,将会话中间件配置为忽略任何不使用req.session
的路径
如果任何处理程序没有写入会话(可能它只从会话中读取),则设置req.session=null调用res.end()之前的code>代码>。那么它就不会被重新保存
如果一次只有一个请求对会话执行读-修改-写操作,则不太可能发生碰撞。我希望在将来,Connect将有一个更精确的会话中间件,但当然API将比我们现在的更加复杂。我提交了一份报告,但几分钟后发现了问题所在。不确定您是否有相同的问题,但为了完整性:
在我的例子中,我通过转到进行测试,但OAuth提供程序正在重定向到。相同的框/服务器/网页,但不同的域名意味着浏览器发送不同的cookie,因此express获得不同的会话ID和会话数据。当我开始在开始测试时,一切正常。我的代码在结构上与您的代码相似。然而,在我的例子中,我的POST操作源自JQuery$.POST函数。然而,我不知道这是否会造成明显的差异
我最后不得不做的是在我的快速路由例程中的操作后定义的末尾发送一个“垃圾”响应,即
res.send(“hoo-hee-ha-ha不重要的垃圾数据”)代码>
通过在最后包含这个函数,我能够触发一个success函数(用于AJAX post尝试的回调)。我在那里插入了重定向,而不是将其放在快速路线中
与ajaxpostwindow.redirect()一起使用代码>
不要与AJAX Post一起使用:$res.redirect(“someurl”)代码>
这是因为浏览器显然不会在AJAX响应时重定向,所以您必须使用Javascript,如下所述:
希望这能帮助到别人,它为我解决了问题,和平。只是与同样的问题斗争并解决了它。
简单的答案是打电话
Session.save()
明确地说,如果您无法在express会话中回复,请在响应结束时为您呼叫它
谢谢您的详细回复。不幸的是,这并没有解决我的问题。我将静态处理程序移到会话中间件之上,但这是我所能做的一切。所有路由(仅4条)要么直接使用会话,要么通过使用会话的中间件。还有其他想法吗?谢谢你的解释。我在connect上打开了一个问题来跟踪它:omg。你的1。解决方案解决了它。由于某种原因,我的会话在帖子的两页之间终止了。我不知道为什么。但它确实做到了。一旦我将静态文件移到会话中间件之上,它就可以工作了!什么是静态的?我没有这样的东西,当我从路由处理程序设置一次会话变量时,我的数据库中会出现18个重复的会话行。调用API的问题与此完全相同。我很确定会话信息在重定向时丢失了。也就是说,如果我在浏览器中刷新页面,我可以看到我在会话中输入的内容仍然存在。但是,如果我通过从某个外部站点(例如oauth提供程序)重定向到同一页面,会话将完全为空。不确定问题出在哪里。更新:看起来你为重定向请求获得了不同的会话id。我有点喜欢旧的hoo-hee-ha-ha。没什么比这更好的了。谢谢你,安瓦尔!这使我省去了巨大的头痛。他很有魅力。很奇怪。