Letting a server know that a tab has closed

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
Archgeek
Posts: 264
Joined: Wed May 02, 2007 6:00 am UTC
Location: Central US
Contact:

Letting a server know that a tab has closed

Postby Archgeek » Thu Apr 10, 2014 3:48 pm UTC

AJAX seems to be kicking my butt, here. I'm using a javascript with onbeforeunload and a few filters (http://eureka.ykyuen.info/2011/02/22/jq ... sed-event/) to catch when a browser window (probably a tab) has been closed; however I cannot seem to get the message back to my php script with any actual success. I've got the following:

Code: Select all

function endSession() {
   // Browser or broswer tab is closed
    // Do sth here ...
    if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
       xmlhttp=new XMLHttpRequest();
    }
   /* xmlhttp.onreadystatechange=function(){
       if (xmlhttp.readyState==4 && xmlhttp.status==200){
          document.getElementById("submit").value=xmlhttp.responseText;
       }
    }*/
    /*xmlhttp.onreadystatechange=function(){
       alert(xmlhttp.statusText);
    }//*/
    //xmlhttp.open("GET", uri + "tabClosed.php?tabClosed=true",true);  //uri's defined elsewhere
    /*http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    http.setRequestHeader("Connection", "close");*/
    //xmlhttp.send();//*/
    //alert(xmlhttp.statusText);
    alert("butts!");
}

None of those commented bits actually work. Even the alert at the end fails to happen if I dare to do anything with xmlhttp other than create it. All I actually need is to get that query string to a php file that can shove it in $_SESSION, but I'm not sure if I should have the server send back a dummy string or what. (I've tried it, as the php file looks like:

Code: Select all

<?php
session_start();
$_SESSION['tabClosed'] = $_GET['tabClosed'];
print($_GET['tabClosed']);
but to no actual avail. Is "sth" actually a thing? I presumed it was a typo of "stuff", but I'm not so sure at this point.

All elucidation appreciated, and sorry for being a pest of late.
"That big tube down the side was officially called a "systems tunnel", which is aerospace contractor speak for "big tube down the side."

User avatar
Archgeek
Posts: 264
Joined: Wed May 02, 2007 6:00 am UTC
Location: Central US
Contact:

Re: Letting a server know that a tab has closed

Postby Archgeek » Thu Apr 10, 2014 6:34 pm UTC

Hahah, nevermind, I've fixed the problem and answered my questions with SCIENCE.

It turns out the browser (IE 8, blugh) in question uses an MSXML2 ActiveX object and not the proffered XMLHttpRequest, in spite of that comment there...so I needed a block like this:

Code: Select all

if (window.XMLHttpRequest) { // Mozilla, Safari,...
       httpRequest = new XMLHttpRequest();
       alert('window.XMLHttpRequest');
       if (httpRequest.overrideMimeType) {
         /* set type accordingly to anticipated content type */
         //httpRequest.overrideMimeType('text/xml');
         httpRequest.overrideMimeType('text/html');
       }
     } else if (window.ActiveXObject) { // IE
       try {
          //yeah, it's this one
         httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
       } catch (e) {
         try {
           httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
           alert('not MSXML2 ActiveX');
         } catch (e) {
            alert('not Microsoft ActiveX');
         }
       }
     }
     if (!httpRequest) {
       alert('Cannot create XMLHTTP instance');
       return false;
     }

It also turns out that that readystatechange function isn't needed, one can just send data to the server, and as such, there's no need for a dummy string from the php, it can just receive the query string and be on its way.

Amusing how these things always work out right after asking for help.
"That big tube down the side was officially called a "systems tunnel", which is aerospace contractor speak for "big tube down the side."

User avatar
Xanthir
My HERO!!!
Posts: 5413
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Letting a server know that a tab has closed

Postby Xanthir » Fri Apr 11, 2014 3:38 am UTC

Also: XHR requests aren't guaranteed to complete before the tab is closed. The browser is allowed to abort them if it feels like the request is taking too long.

The one guaranteed way to send a message in a beforeunload handler is, for stupid legacy reasons, to send it as a GET request by encoding it into an <img>'s src attribute. Don't... don't ask why this works, but it's guaranteed to do so by the relevant standards. Just make a new Image(), set the src attribute, and Bob's your uncle.

Note, though, that there's no guaranteed way to know when a tab is closed. The browser might be closed directly via the task manager, or the computer might turn off. The most reliable way to tell when something has closed is to use a heartbeat message, and assume the tab is closed when it misses some number of heartbeats.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
Archgeek
Posts: 264
Joined: Wed May 02, 2007 6:00 am UTC
Location: Central US
Contact:

Re: Letting a server know that a tab has closed

Postby Archgeek » Mon Apr 14, 2014 4:19 pm UTC

Good to know, that.

Wow...that is public transport reducingly special. I'll keep it in mind though, in case the existing code generates frequent failures.

Indeed there is not, which is why I've padded things a bit. An array of tabs is being tracked, and it can have a max size set. When there are too many tabs when a new one is registered, the user sees an error, so to delay that, any tab which sends a probable closure message is marked as deprecated, and the oldest one is overwritten instead of erroring when the error condition comes up. However, if the tab is ever accessed again before this occurs, it is removed from the deprecated queue and no longer in danger of being overwritten. (Also if javascript is enabled the user is invited to close a few tabs to recover from the error condition.)
"That big tube down the side was officially called a "systems tunnel", which is aerospace contractor speak for "big tube down the side."

User avatar
chridd
Has a vermicelli title
Posts: 843
Joined: Tue Aug 19, 2008 10:07 am UTC
Location: ...Earth, I guess?
Contact:

Re: Letting a server know that a tab has closed

Postby chridd » Fri Apr 25, 2014 4:10 am UTC

Xanthir wrote:Note, though, that there's no guaranteed way to know when a tab is closed. The browser might be closed directly via the task manager, or the computer might turn off. The most reliable way to tell when something has closed is to use a heartbeat message, and assume the tab is closed when it misses some number of heartbeats.
...but the computer can go to sleep with the browser open (mine often does), or it can lose its internet connection for long periods of time, so even that's not perfectly reliable (and it's a case that one should account for... I know that I, for one, wouldn't want to deal with a bunch of error messages each time I wake up my computer).

Archgeek wrote: Is "sth" actually a thing? I presumed it was a typo of "stuff", but I'm not so sure at this point.
I'd assumed it was an abbreviation of "something"...
~ chri d. d. /tʃɹɪ.di.di/ (Phonotactics, schmphonotactics) · she · Forum game scores
mittfh wrote:I wish this post was very quotable...


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 6 guests