在浏览器关闭之前,我不希望会话无效

时间:2010-07-31 13:58:05

标签: php session

将会话ID存储在客户端计算机上没有问题,而且非常简单。问题是将实际会话存储在服务器上,直到我真的觉得我已经完成了它。

垃圾收集器非常清楚它是如何工作的。我无法阻止它在一定时间内清理垃圾。我可以将时间设置得很高,但是然后冒着会话劫持的风险(这仍然非常小并且劫持会话对于破解者来说没什么用处)或者会话目录过度拥挤(猜测你真的需要巨大的流量来实现这一点)但仍然......)

使用javascript进行常规http请求的唯一解决方案是阻止GC在客户端空闲时最终获取会话吗?

提前致谢

4 个答案:

答案 0 :(得分:3)

非常好。您无法可靠地检测到浏览器窗口已关闭。尽管JS提供寡妇关闭事件,但您不应该使用它,因为通过单击“关闭”按钮关闭浏览器只是客户端会话可能结束的几种方式之一。

其他可能性:

  1. 浏览器崩溃
  2. 客户端的计算机崩溃
  3. 网络连接已死
  4. 有些浏览器不会考虑关闭窗口卸载事件(Opera甚至不考虑通过在地址栏中键入地址并卸载事件来关闭选项卡或远离网页)

答案 1 :(得分:1)

如果你想要的是永远保持会话,那么定义一个自定义垃圾收集器。

但是,您无法确定用户何时关闭其浏览器。最简单的方法是设置一个JavaScript或META REFRESH pinger,只要他们打开你的页面就会一直通知你 - 但你不知道他们仍然没有将浏览器打开到另一个页面。 / p>

答案 2 :(得分:0)

我相信您可以使用XMLHTTPRequest(Ajax技术)将您的服务器ping到例如带有简单session_start()的空白页面;比方说,每15分钟一次(默认PHP会话超时为20秒),因此它们不会使服务器过载。

但是,如果您确实希望保留数据,则在浏览器退出时会清除没有明确过期时间的cookie,因此您可以在cookie中存储存储密钥。这比会话有一个优势 - 如果客户端的网络连接中断,会话仍然有效。但这可能会导致更多的会议劫持。

如果您正在谈论在浏览器会话中保持登录持久性,那么首选cookie方式,并且全世界许多网站都在使用它,包括Drupal,Wordpress和Joomla! CMS。

答案 3 :(得分:0)

有许多方法,其中没有一个是可取的。我会列出我学到的东西。 注意:我希望人们理解这一点。大多数人都认为我只想在客户端关闭浏览器时注销。事实并非如此,我只想释放资源而不是20分钟的滞后。大多数开发人员只是升级计算机我想。

1)继续从客户端脚本ping您的服务器,因此,它将使“短会话”保持活跃状态​​。 这显然会增加服务器的流量,显然不会立即注销,因为你不想像每秒一样ping。

2)使用来自客户端浏览器的Javascript。到目前为止,我认为它们中的任何一个都没有工作,即使是现有的IE代码示例,clienX也将是>无论如何,这是迄今为止对我有用的代码。仅在IE上,因为Firefox事件现在对我不起作用。我大致计算了关闭按钮在屏幕上的位置,并确定客户是否点击了该区域。如果刷新按钮太靠近关闭按钮(x明智),它会认为你点击了关闭按钮,但是,这是一种罕见的情况。

<head runat="server">
    <title>Untitled Page</title>
<script type="text/javascript">
    function test(event) {
        var X = window.event ? window.event.screenX : event.clientX;

        // IE only because event.clientX for FF = undefined (event.clientX IS the FF way).
        if (X == null) {
            alert("No X");
            return;
        }

        var left = window.screenLeft ? window.screenLeft : window.screenX;
        var winwidth = document.body.clientWidth ? document.body.clientWidth : window.outerWidth;
        var leftMargin = document.body.leftMargin ? parseInt(document.body.leftMargin, 10) : 0;
        var rightMargin = document.body.rightMargin ? parseInt(document.body.rightMargin, 10) : 0;
        var resultX = X - (window.screenLeft + winwidth + leftMargin + rightMargin); // scroll bar width is not calculated.
        var Y = window.event ? window.event.clientY : event.clientY;

        if (resultX > -25 && Y < 0)
            alert("logging out");
    };
</script>

</head>
<body onbeforeunload="test(event);">