3

我今天在修改会话库时遇到了一个问题,这可能是我第一次在后端脚本上看到特定于浏览器的问题。我希望有人能解释一下。

会话库的基本工作方式是:实例化时,它会在客户端机器上检查名为“id”的 cookie(以 uniqid 结果的形式)。如果找到 cookie,脚本会检查该 cookie 以及用户代理字符串的散列副本与会话表中的条目。如果找到匹配条目,脚本将恢复会话。如果没有找到名为 'id' 的 cookie,或者会话表中不存在匹配条目,则脚本会同时创建两者。我认为相当标准。

现在这是奇怪的部分:在 Firefox 中,一切都按预期工作。用户获得一个会话,只要未超过 24 小时不活动,他将始终在连接后恢复该会话。但是当我在 Chrome 中访问该页面时,即使它看起来相同并且似乎正在以相同的顺序执行查询,我在会话表中看到了两个条目。会话共享一个代理字符串,但 id 不同,时间戳日志表明在为用户创建的会话之后不久(一秒内)创建了幽灵会话。

出于调试目的,我一直在执行查询时将查询打印到屏幕上,这是我在 Chrome 应该打开一个会话并且以某种方式打开两个会话时所看到的示例:

// Attempting to resume a session
SELECT id FROM sessions WHERE id = '4fd24a5cd8df12.62439982' AND agent = '9bcd5c6aac911f8bcd938a9563bc4eca'

// No result, so it creates a new one
INSERT INTO sessions (id, agent, start, last) VALUES ('4fd24ef0347f26.72354606', '9bcd5c6aac911f8bcd938a9563bc4eca', '1339182832', '1339182832')

// Clear old sessions
DELETE FROM sessions WHERE last < 1339096432

以下是我之后在数据库中看到的内容:

id, agent, start, last
4fd24ef0347f26.72354606, 9bcd5c6aac911f8bcd938a9563bc4eca, 1339182832, 1339182832
4fd24ef0857f94.72251285, 9bcd5c6aac911f8bcd938a9563bc4eca, 1339182833, 1339182833

我错过了一些明显的东西吗?我唯一能想到的是 Chrome 可能会在后台创建一个隐藏会话,可能是为了抓取页面。但是,如果是这种情况,那么当我开始将活动会话与用户表中的条目相关联时,它可能会成为一个问题。我一直在寻找我的脚本中可能存在的错误,但到目前为止我还没有发现任何东西,并且在 Firefox 中一切正常。

4

1 回答 1

4

我以前遇到过这种情况,同样感到困惑。从几个月前开始,Chrome 就启用了预取功能。因此,为了加快用户的感知速度,它会抓取页面上的大多数链接,并提前部分检索和呈现它们。非常适合最终用户,因为如果您使用宽带,它可以真正减少页面更改时间。

不幸的是,对于我们 Web 开发人员来说,它会导致像上面这样的混乱。例如,当 Chrome 用户访问网站但尚未分配 cookie 或会话,但浏览器已预先获取多个页面并分配了多个会话时,就会发生这种情况。

因此,假设某人访问了一个带有指向您 PHP 脚本不同区域的链接的页面,并且该脚本旨在为所有访问者分配一个 cookie……如果 Chrome 同时或接近它获取其中两个页面,PHP 将最终分配不同的会话,因为 Chrome 中的另一个线程在完成其他分配之前基本上需要一个新的会话/cookie。

我知道有两种解决方案:一种是用于处理预渲染的 Google 的 JavaScript API,我还没有发现它特别好。另一种方法是在从 PHP 分发会话和 cookie 时执行更严格的检查。要么不将会话分配给来宾用户,要么添加一些额外的检查(IP、主机名等)。

希望有帮助。

于 2012-06-20T15:13:14.977 回答