Skip to content Skip to sidebar Skip to footer

In A $.ajax Callback, How Do I Distinguish An Unreachable Server From A User Navigating Away?

Situation: You've got a few $.ajax requests to the server that are still running. They all error out with xhr.status === 0 and xhr.readyState === 0. Possible causes: The server i

Solution 1:

(This answer is an abstract of another answer, for clarity's sake by the OP's request)
If a window level flag isn't working, the next dom level event to test before $(window).unload is window.onbeforeunload. Is that a viable option?

Around your AJAX method:

var running = true;
// do this only once!!!
var _obunload = ( window.onbeforeunload )? window.onbeforeunload: function(){};
window.onbeforeunload = function() 
{ 
     _obunload.call( window );
     running = false;
}
xhr.onreadystatechange = function()
{
    if( !xhr.status && !xhr.readyState && running )
    {
        // warning! warning! danger Will Robinson!
        // there was a server error
    }
    else if( !xhr.status && !xhr.readyState )
    {
        // user did something... Who gives?
    }
    running = false;
}

Solution 2:

You can check for a timeout response from the server:

timeout:500,
error: function(jqXHR, textStatus, errorThrown) {
    if(textStatus==="timeout") {
        alert("got timeout");
    } else {
        // Some other error
    }
}

Solution 3:

Idea 3

Well, there is always the possibility of faking a delay from the non-existent server:

var running = true;
xhr.onreadystatechange = function()
{
    if( !xhr.status && !xhr.readyState )
    {
        // wait a short while to see whether the page is unloading.
        setTimeout( unloadTest, 250 );
    }
    else
    {
        running = false;
    }
}

function unloadTest()
{
    // running will be set to false by onbeforeunload, which means this
    // should only be true if there was some form of server error.
    if( running ) // Regnad? Robin Williams?
}

Then, elsewhere:

// (using generic JS, you can use $(window).bind( 'beforeunload' ...
window.onbeforeunload = function() 
{ 
     running = false;
} 

Idea 2

Well, if below isn't working, the next dom level event to test before $(window).unload is window.onbeforeunload. Is that a viable option?

Around your AJAX method:

var running = true;
xhr.onreadystatechange = function()
{
    if( !xhr.status && !xhr.readyState && running )
    {
        // warning! warning! danger Will Robinson!
        // there was a server error
    }
    else if( !xhr.status && !xhr.readyState )
    {
        // user did something... Who gives?
    }
    running = false;
}

Then, elsewhere:

// (using generic JS, you can use $(window).bind( 'beforeunload' ...
window.onbeforeunload = function() 
{ 
     running = false;
} 

Original post (apparently is not working)

Why not set a flag on the window itself?

<html>
   <script type="text/javascript">
        // window.currentTime will update *first* after every page refresh.
        window.currentTime = new Date().getTime()
   </script>
   <!-- continue as normal -->

Then, when you're about to call $.ajax:

// winTime is bound to window.currentTime at the time of the original query.
var winTime = window.currentTime;
// using onreadystatechange because it looks like you're looking for that in your
// question. This can be easily adapted to $.ajax, however.
xhr.onreadystatechange = function()
{
    if( !xhr.status && !xhr.readyState && winTime == window.currentTime )
    {
        // warning! warning! danger Will Robinson!
        // there was a server error
    }
    else if( !xhr.status && !xhr.readyState )
    {
        // user did something... Who gives?
    }
}

Post a Comment for "In A $.ajax Callback, How Do I Distinguish An Unreachable Server From A User Navigating Away?"