views:

793

answers:

1

I have a web app driven by a servlet that times out users' sessions after a period of inactivity by redirecting to a login page. I had code in place on the web client that checked for this, essentially similar to the following:

function error(request, errtype) {
    if (request.status == 302) {
        // Display a "timed out" dialog, then:
        window.location = request.getResponseHeader("Location");
    }
}

However, recently this scheme stopped working; on timeout, the request.status was 0. Using Firebug I could see that the same HTTP 302 response was being returned.

I read the spec for XMLHttpRequest carefully, and found this section:

If the redirect does not violate security (it is same origin for instance), infinite loop precautions, and the scheme is supported, transparently follow the redirect while observing the same-origin request event rules.

Otherwise, this is a network error.

I hadn't even known that clients were supposed to automatically follow redirects that they get in response to Ajax requests; the browsers I care about didn't do that before, since my code above used to work. I recently upgraded my version of Firefox, which now perhaps is following the spec more closely. The network error prescribed by the spec would explain the zero response code I'm seeing. However, the redirect I'm getting is to the same host (albeit on a different port), there shouldn't be an infinite loop, and the scheme remains HTTP, so I don't understand why I'm getting a network error.

Any ideas?

A: 

how you are you getting to this function? if you're only sending it to "error" on a 200 status obviously this wouldn't work...

request.onreadystatechange = function( )
{
   if( this.readyState == 4 )
   {
      // if we got a 200
      if( this.status == 200 ){ /* cool */ }

      // if we got anything else
      else { error( this, this.status ); }
   }
};

But I'm assuming you know this. Also, you should probably include .href at the end of window.location and possibly a default location just in case

// Display a "timed out" dialog, then:
window.location.href = request.getResponseHeader("Location") || defaultPage;

If this doesn't work, you might wanna try a different status in the onreadystatechange method, as some browsers may interpret a non 200 status as an error. These could be (from that same spec you're reading from):

0 (if it's considered aborted after unset, though unlikely)
2 (headers-sent) as that 302 code is actually a HTTP header

good luck!

Dan Beam
I'm using jQuery's Ajax functionality, which I perhaps should have mentioned. jQuery doesn't attach the handler function to the XMLHttpRequest object; it polls the object and invokes the user-supplied callback itself. In any case, I poked around jQuery's internals a bit and printed out the state of the XHR object when the Ajax call returned, and it was, as described, basically empty, apparently indicating a network error. But in IE and less-current versions of Firefox, the XHR object contains normal data indicating a 302 response.
Sean