在$ .ajax回调中,如何区分无法访问的服务器和导航的用户?

时间:2011-08-08 04:50:13

标签: javascript ajax jquery

情况:

您还有一些$ .ajax请求仍在运行的服务器上。它们都出错了xhr.status === 0和xhr.readyState === 0。

可能的原因:

  • 服务器已关闭(编辑:无法访问 - 未返回任何标头或任何内容)。
  • 用户点击链接/刷新页面/以其他方式导航。

我想在第一种情况下弹出一个对话框,但忽略第二种情况。我如何在完整的方法中区分这两者?完整的方法在$(window).unload事件之前被触发,所以我不能用它来确定用户是否点击了。我也可以使用setTimeout来尝试等待下一页加载,但这很脏。还有什么我可以做的吗?

3 个答案:

答案 0 :(得分:1)

(这个答案是另一个答案的摘要,为了清楚起见,OP的要求)
如果窗口级别标志不起作用,则在$(window).unload之前要测试的下一个dom级别事件是window.onbeforeunload。这是一个可行的选择吗?

围绕你的AJAX方法:

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 :(得分:0)

您可以检查服务器的超时响应:

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

答案 2 :(得分:0)

创意3

嗯,总是有可能从不存在的服务器伪造延迟:

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?
}

然后,在其他地方:

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

创意2

好吧,如果下面的内容不起作用,那么$(window).unload之前要测试的下一个dom级别事件就是window.onbeforeunload。这是一个可行的选择吗?

围绕你的AJAX方法:

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;
}

然后,在其他地方:

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

原帖(显然不起作用)

为什么不在窗口上设置一个标志?

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

然后,当您打算致电$.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?
    }
}