Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
520 views
in Technique[技术] by (71.8m points)

php - destroy session on window close?

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. =)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...