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


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.


You could use JavaScript to implement an OnUnload event and use AJAX to communicate the user leaving to the site. However, the event also occurs when they navigate to another page. You'd have to implement something like "if the user doesn't request a new page within x seconds", he has left my site, but it will never work reliably if you take into account the possibility of multiple windows being open.

The only way to do this, is to do regular AJAX postbacks to the server that the user is still on your page. It still wouldn't be instant though.

You could try experimenting with the script you're posting back to. Build in a significant waiting period before responding. When the user navigates away from your page, the browser would probably abort the XmlHttpRequest that is in progress. Your server side script could register the client disconnecting and conclude that the user has left... again, unless they proceed to load another page.

In short, there is no definite way to do this in a clean manner.


You could separate the concepts of "showing as logged in" actually being logged in. For instance, every time a user requests a page you can mark them as "online" for another few minutes but you can set their actual login timeout to several hours. In this scheme if a user walked away from their computer the site would show them as "offline" after a few minutes but they could still return in say an hour or so and not have to log back in.