In the $ .ajax callback, how to distinguish an unreachable server from a user going further?

Situation:

You have several $ .ajax requests on a server that is still running. All of them fail with xhr.status === 0 and xhr.readyState === 0.

Possible reasons:

  • Server is down (EDIT: as unavailable - no header returns or anything else).
  • The user clicked a link / updated the page / otherwise sailed.

I would like to open a dialogue in the first case, but ignore the second. How can I distinguish between these two methods in my full method? The full method runs before the $ (window) .unload event, so I cannot use this to determine if the user was clicked. I could also use setTimeout to try to wait for the next page to load, but it's dirty. Is there anything else I can do?

+3
source share
3 answers

(This answer is a summary of another answer, for clarity in the OP request)
If the window-level flag does not work, the next dom-level event for testing before $(window).unloadis equal window.onbeforeunload. Is this 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;
}
+1

:

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

Idea 3

Well, there is always the option to fake a delay from a 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, in another place:

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

Idea 2

Well, if below does not work, the next dom level event to test is up $(window).unloadto window.onbeforeunload. Is this 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, in another place:

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

Original post (apparently not working)

Why not set a flag in 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 are going 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?
    }
}
0
source

Source: https://habr.com/ru/post/1708390/


All Articles