为啥某些 Flask 会话值在关闭浏览器窗口后会从会话中消失,但稍后会在没有我添加它们的情况下重新出现?

Posted

技术标签:

【中文标题】为啥某些 Flask 会话值在关闭浏览器窗口后会从会话中消失,但稍后会在没有我添加它们的情况下重新出现?【英文标题】:Why do some Flask session values disappear from the session after closing the browser window, but then reappear later without me adding them?为什么某些 Flask 会话值在关闭浏览器窗口后会从会话中消失,但稍后会在没有我添加它们的情况下重新出现? 【发布时间】:2012-11-25 10:47:29 【问题描述】:

所以我对 Flask 会话的理解是,我可以像字典一样使用它,并通过以下方式为会话添加值:

session['key name'] = '这里有一些值'

而且效果很好。

在我使用 AJAX 发布客户端调用的路由上,我为会话分配了一个值。它工作正常。我可以单击我网站的各个页面,并且该值保留在会话中。但是,如果我关闭浏览器窗口,然后返回我的站点,我在其中的会话值就消失了。

所以这很奇怪,您会认为问题在于会话不是永久性的。我还实现了 Flask-Openid 并使用会话来存储信息,如果我关闭浏览器窗口并再次打开它,确实会持续存在。我在关闭浏览器窗口后也检查了cookie,但在返回我的站点之前,cookie确实还在。

另一个奇怪的行为(可能相关)是,当我访问 AJAX 发布路由并分配正确的值时,我为测试目的而写入会话的一些值将消失。所以这很奇怪,但真正奇怪的是,当我关闭浏览器窗口并再次打开它,从而失去了我试图保留的价值时,我之前失去的价值实际上又回来了!它们没有被重新分配,因为我的 Python 文件中没有代码可以重新分配这些值。

这里有一些输出可以帮助更清楚。它们都是从真实页面的路由输出的,而不是我上面提到的 AJAX 发布路由。

这是我分配了要存储在会话中的值后的输出。值键是 'userid' - 所有其他值都是我在尝试解决此问题时添加的虚拟值。 'userid': 8 只要我不关闭浏览器窗口,就会留在会话中。我可以访问其他路线,并且价值将保持原样。

['session.=', <SecureCookieSession 'userid': 8, 'test_variable_num': 102, 'adding using before request': 'hi', '_permanent': True, 'test_variable_text': 'hi!'>]

如果我关闭浏览器窗口并返回站点,但不重做 AJAX 发布请求,我会得到以下输出:

['session.=', <SecureCookieSession 'adding using before request': 'hi', '_permanent': True, 'yo': 'yo'>]

'yo' 值不在第一个输出中。我不知道它是从哪里来的。我在我的代码中搜索了“yo”,但没有任何实例可以让我在任何地方分配该值。我想我可能在几天前​​将它添加到会话中。所以它似乎是持续存在的,但是在写入其他值时被隐藏了。

最后一个是我再次访问 AJAX 发布路由,然后转到使用调试打印出密钥的页面。与我在上面粘贴的第一个输出相同的输出,正如您所期望的那样,'yo' 值又消失了(但如果我关闭浏览器窗口它会回来)

['session.=', <SecureCookieSession 'userid': 8, 'test_variable_num': 102, 'adding using before request': 'hi', '_permanent': True, 'test_variable_text': 'hi!'>]

我在 Chrome 和 Firefox 中都对此进行了测试。

所以我觉得这很奇怪,我猜这源于对会话如何工作的误解。我认为它们是字典,只要我将会话设置为永久并且 cookie 没有被删除,我就可以将字典值写入其中并在几天后检索它们。

知道为什么会发生这种奇怪的行为吗?

【问题讨论】:

【参考方案1】:

如果您没有设置session.permanent = True,一旦关闭浏览器,Flask 会话将被删除。这就是烧瓶会话的定义方式,并在文档中有所提及。

如果您确实将会话设置为永久,则默认为会话将​​持续的 31 天。您也可以通过session.permanent_session_lifetime 更改该默认值。这意味着即使您关闭浏览器,会话也将持续存在,当然,除非您手动删除 cookie 本身。

在您的情况下,我不确定您是如何使用 AJAX 调用的,但总的来说,以上关于默认烧瓶会话应该适用。

【讨论】:

【参考方案2】:

原来问题出在多域 cookie 上。我在 127.0.0.1:5000 本地运行该站点,但有时该站点是在 localhost:5000 访问的 - 因此每个域都有一个单独的 cookie。这就解释了为什么数据会消失然后又重新出现。它只是与不同的域相关联。

以下只是额外的细节

这是因为 Facebook 不喜欢域名的 IP 地址。所以在本地开发时,我使用的是 127.0.0.1:5000 但 Facebook 回调 url 是 localhost:5000。这很好用,因为 Flask 会在两个 url 上接收请求并将它们视为相同 - 所有路由都按预期工作。除了与不同 url 相关联的会话 cookie。

【讨论】:

以上是关于为啥某些 Flask 会话值在关闭浏览器窗口后会从会话中消失,但稍后会在没有我添加它们的情况下重新出现?的主要内容,如果未能解决你的问题,请参考以下文章

Flask – 具有相同名称的多个会话 cookie

Flask 会话忘记请求之间的条目

五十九:Flask.Cookie之flask设置cookie过期时间

如何使用会话存储以角度区分窗口关闭和窗口刷新

为啥某些联系人会从 android 上的应用程序中被审查?

为啥我的js关闭窗口没执行呢