销毁窗口关闭会话? [英] destroy session on window close?

查看:72
本文介绍了销毁窗口关闭会话?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在php中创建了具有注销功能等的登录系统.但是我需要在关闭窗口时销毁会话.这需要立即"或尽可能快地将用户状态更改为脱机.我真的不想在会话上设置时间,因为这使用户不得不一直登录.

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

解决方案

默认情况下,浏览器关闭时,PHP发送的所有会话cookie都会被删除.但据我所知,您想在其他浏览器上显示通知.这有点难,也不是很好.您必须使用 window.onclose 事件处理程序并发出Ajax请求(我认为这应该是一个同步请求)到服务器,以信号通知窗口关闭.而且同步调用不是很好...

另一方面,另一个浏览器将不得不通过其他Ajax请求拉动服务器,以查看某个用户何时注销.

所有这些Ajax请求都提出了一个丑陋的解决方案.

更新:

正如Thorarin和Jonathan Fingland所说,多个窗口可能存在问题(不是选项卡,因为window.onclose会在窗口上触发而不是选项卡),但我相信也可以解决此问题.如果第一个窗口设置的cookie number_of_windows = 1,对于每个打开的窗口都递增,那么在窗口关闭时,仅当number_of_windows等于1时才会触发Ajax请求,否则只会使number_of_windows递减.

更新2:

上述解决方案确实在使用多个打开的选项卡时会遇到麻烦.我正在考虑如何减轻这种情况.

更新3:

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

在服务器端,Ajax调用所请求的脚本应更新数据库中的某些条目,表明用户可能已关闭页面.您如何看待她是否不仅仅是在访问您网站上的新页面?简单,在每个页面访问中,您都需要检查数据库中该会话的可能已注销"值,如果有,则将它们标记为false(用户已登录),否则用户将继续在数据库中注销(true标志).

这很麻烦,但这是我想到的唯一解决方案,因为我无法确定JavaScript中的页面重新加载或类似内容.另外,我没有做广泛的测试,更是一个主意.无论如何,我不会推荐此解决方案.对每个更改的页面进行Ajax请求都是过分的,实际上会使服务器上的点击次数翻倍,而无需计算其他浏览器进行的轮询.

这是代码段.顺便说一句,bakery.js是document.cookie的小型包装.您可能在github上找到其源代码.

<!DOCTYPE html>

<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="bakery.js"></script>
<script type="text/javascript">
var logout = function() {
    var xhr = new XMLHttpRequest;
    xhr.open("GET", "logout.php", false);
    xhr.send(null);
};

window.onload = function() {
    var winNumber = parseInt(IGS.Bakery.getCookie("winNumber"), 10) || 0;
    IGS.Bakery.setCookie("winNumber", winNumber + 1);
};

window.onunload = function() {
    var winNumber = parseInt(IGS.Bakery.getCookie("winNumber"), 10) || 0;
    IGS.Bakery.setCookie("winNumber", winNumber - 1);

    if (winNumber === 1) {
        logout();
    }
};

var showCookies = function() {
    alert(IGS.Bakery.getCookie("winNumber"));
};
</script>
</head>
<body>

<a href="#" onclick="showCookies();">show</a>

</body>
</html>

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

I have a created a login system in php with logout functions etc. But I need the session to be destroyed on window close. This needs to be "instant" or as fast as possible to change the users status to offline. I dont really want to set a time on the session as this is annoying for the user having to login all the time.

Any suggestions welcomed, thanks. =)

解决方案

By default all session cookies sent by PHP are deleted when the browser closes. But as far as I see, you want to show notifications on other browsers. This is a little bit harder and not quite nice. You'd have to use the window.onclose event handler and issue an Ajax request (I believe it should be a synchronous request) to the server to signal the window closing. And synchronous calls aren't that nice...

On the other hand, the other browser will have to pull the server with other Ajax request to see when a certain user has logged off.

All these Ajax requests make for an ugly solution.

Update:

As Thorarin and Jonathan Fingland said, there may be problems with multiple windows (not tabs, as window.onclose fires on windows not tabs), but I believe there's a solution to this problem too. If the first window sets a cookie number_of_windows = 1, that is incremented for each opened window, then on window close, the Ajax request is fired only if number_of_windows equals to 1, otherwise it just decrements number_of_windows.

Update 2:

The above solution would, indeed, have troubles with multiple open tabs. I'm thinking how to alleviate that.

Update 3:

OK, I figured out some sort of solution but it's not working in IE6, don't know about other IE version. The below snippet keeps track of the number of open windows and tabs (except for IE which doesn't update document.cookie in real time between windows, but I believe it could be solved with some IE proprietary features). Then on each page unload, which means even navigating from page to page on the same web site, the script checks to see how many open windows are. If it's the only open window/tab, then it issues an Ajax request. This is the first part of the solution. Now, the second part.

On the server-side, the script that the Ajax call is requesting, should update some entry in a DB saying that the user may have closed the page. How do you figure whether she's not just accessing a new page on your site? Simple, on every page access you check the DB for "maybe logged out" values for that session, and if there are you flag them as false (the user is logged in), otherwise the user keeps being logged out in the DB (true flag).

It's messy but it's the single solution that came to my mind, as there's no way I could determine a page reload or the like in JavaScript. Also, I didn't do extensive testing, is more an idea. Anyway, I wouldn't recommend this solution. An Ajax request for every changed page is overkill and literally doubles the hits on the server, without counting the polling done by other browsers.

Here's the snippet. By the way, bakery.js is a small wrapper for document.cookie. You may find its source here on github.

<!DOCTYPE html>

<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="bakery.js"></script>
<script type="text/javascript">
var logout = function() {
    var xhr = new XMLHttpRequest;
    xhr.open("GET", "logout.php", false);
    xhr.send(null);
};

window.onload = function() {
    var winNumber = parseInt(IGS.Bakery.getCookie("winNumber"), 10) || 0;
    IGS.Bakery.setCookie("winNumber", winNumber + 1);
};

window.onunload = function() {
    var winNumber = parseInt(IGS.Bakery.getCookie("winNumber"), 10) || 0;
    IGS.Bakery.setCookie("winNumber", winNumber - 1);

    if (winNumber === 1) {
        logout();
    }
};

var showCookies = function() {
    alert(IGS.Bakery.getCookie("winNumber"));
};
</script>
</head>
<body>

<a href="#" onclick="showCookies();">show</a>

</body>
</html>

Forgot to mention. window.onclose is not cross-browser.

这篇关于销毁窗口关闭会话?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆