关闭窗口关闭会话?

时间:2009-06-06 13:19:11

标签: php

我在php中创建了一个登录系统,具有注销功能等。但我需要在窗口关闭时销毁会话。这需要“即时”或尽可能快地将用户状态更改为脱机。我真的不想在会话上设置时间,因为这对于必须一直登录的用户来说很烦人。

欢迎任何建议,谢谢。 =)

3 个答案:

答案 0 :(得分:6)

默认情况下,浏览器关闭时会删除PHP发送的所有会话cookie。但据我所知,您希望在其他浏览器上显示通知。这有点难,不太好。您必须使用window.onclose事件处理程序并向服务器发出Ajax请求(我认为应该是同步请求)以通知窗口关闭。同步电话不是那么好......

另一方面,其他浏览器必须使用其他Ajax请求拉取服务器以查看某个用户何时注销。

所有这些Ajax请求都会产生难看的解决方案。

<强>更新

正如Thorarin和Jonathan Fingland所说,多个窗口可能存在问题(不是标签,因为窗口上的窗口不会触发,但是我相信这个问题也有解决方案)。如果第一个窗口设置了一个cookie number_of_windows = 1,对于每个打开的窗口都会递增,那么在窗口关闭时,只有当number_of_windows等于1时才会触发Ajax请求,否则它只会递减{{ 1}}。

更新2:

上述解决方案确实会出现多个打开的标签问题。我正在考虑如何减轻这一点。

更新3:

好的,我想出了某种解决方案,但它在IE6中不起作用,不知道其他IE版本。下面的代码片段记录了打开的窗口和标签的数量(除了IE之间没有在Windows之间实时更新document.cookie,但我相信它可以通过一些IE专有功能来解决)。然后在每个页面卸载,这意味着甚至在同一个网站上从一个页面导航到另一个页面,脚本检查以查看有多少打开的窗口。如果它是唯一打开的窗口/选项卡,则它会发出Ajax请求。这是解决方案的第一部分。现在,第二部分。

在服务器端,Ajax调用请求的脚本应更新数据库中的某些条目,表示用户可能关闭了该页面。您如何判断她是否只是访问您网站上的新页面?很简单,在每个页面访问时,您检查数据库中该会话的“可能已注销”值,如果您将它们标记为false(用户已登录),则用户将继续在数据库中注销(true标志)。

它很乱,但它是我想到的单一解决方案,因为我无法确定JavaScript中的页面重新加载等。另外,我没有做过大量的测试,更多的是一个想法。无论如何,我不推荐这个解决方案。对每个更改过的页面的Ajax请求都是过度的,并且在服务器上的命中率实际上是两倍,而不计算其他浏览器完成的轮询。

这是片段。顺便说一句,bakery.js是document.cookie的一个小包装器。您可以找到its source here on github

number_of_windows

忘了提。 window.onclose不是跨浏览器。

答案 1 :(得分:3)

您可以使用JavaScript来实现OnUnload事件,并使用AJAX来传达离开网站的用户。但是,当它们导航到另一个页面时也会发生该事件。你必须实现“如果用户在x秒内没有请求新页面”之类的东西,他已经离开了我的网站,但如果你考虑到多个窗口被打开的可能性,它将无法可靠地工作。 / p>

执行此操作的唯一方法是定期向用户仍在页面上的服务器进行AJAX回发。但它仍然不会是即时的。

您可以尝试使用您要发回的脚本进行试验。在响应之前建立一个重要的等待期。当用户离开您的页面时,浏览器可能中止正在进行的XmlHttpRequest。您的服务器端脚本可以注册客户端断开连接,并断定用户再次离开...,除非他们继续加载另一个页面。

简而言之,没有明确的方法以干净的方式做到这一点。

答案 2 :(得分:1)

您可以将实际登录的“显示为已登录”的概念分开。例如,每次用户请求页面时,您可以将其标记为“在线”几分钟,但您可以设置其实际登录超时几个小时。在这个方案中,如果用户离开他们的计算机,该网站会在几分钟后将其显示为“离线”,但他们仍然可以在一小时左右返回,而不必重新登录。