在Ajax请求中间更改页面

时间:2011-08-02 10:00:05

标签: jquery ajax

如果我发送一些ajax请求,并在请求返回之前立即更改页面(比如关注某个链接)会发生什么?我的意思是我认为XHR对象向网站发送请求,但在检索到响应之前它被删除(因为页面已被更改),那么响应应该发送到哪里?

我问这个问题,因为我的网站出现了一个奇怪的问题。我有一个页面通过Ajax请求从数据存储加载帖子。如果在加载完成之前我单击一个链接,我得到了jQuery.ajax的错误!不知道为什么会这样。

编辑:这是我对ajax的调用。在正常情况下,将调用成功回调。但是当我点击链接时,会调用错误回调!我正在考虑的事情,可能是因为数据应格式化为JSON,但请求在中间切断,因此数据被视为无效导致jQuery调用错误回调?!但那么为什么请求会在中间切断?

$.ajax({
  type: (args.rel == "async" || args.rel == "dialog") ? "GET" : "POST",
  url: href,
  dataType: "json",
  data: args.data ? args.data:{}, // send {} to ensure Content-Length header
  success: function(data){
    if (context) context.removeClass("ajax_wait");
    if (args.hideonwait) $(args.hideonwait).show();
    if (args.showonwait) $(args.showonwait).hide();
    if (spinner) remove_spinner(context, spinner);
    handle_response(args, context, target, data);
  },
  error: function(xhr, status, errorThrown){
    if (context) context.removeClass("ajax_wait");
    if (args.hideonwait) $(args.hideonwait).show();
    if (args.showonwait) $(args.showonwait).hide();
    if (spinner) remove_spinner(context, spinner);
    ajax_error(args, context,
               status + "-" + xhr.status,
               errorThrown ? errorThrown : xhr.responseText);
  }
});

5 个答案:

答案 0 :(得分:10)

技巧是检查XMLHttpRequest对象中的响应头。如果没有响应头(null或空字符串,具体取决于浏览器),则服务器尚未响应。这意味着用户已中止。

$.ajax({
    url: "url-to-go-here",
    success: function() {
    },
    error: function(xhr, textStatus, errorThrown) {
        if(!isUserAborted(xhr)) {
            console.log("Ajax Error")
        }
    }
});

function isUserAborted(xhr) {
  return !xhr.getAllResponseHeaders();
}

Source

答案 1 :(得分:3)

行为似乎是当用户离开页面时,任何未完成的ajax请求都以0作为其状态。 jQuery将此解释为错误,这就是它调用错误处理程序的原因。在错误处理程序中,如果xhr.status == 0,则可以调用成功处理程序调用的相同函数,否则执行所需的错误行为。

答案 2 :(得分:1)

此问题的解决方案很简单,您只需要当前正在运行请求并且如果用户单击任何其他链接,那么您需要提醒用户该请求正在处理中,请等待

要实现此目的,您需要维护一个信号量,在触发任何请求之前设置该信号量,并在完成该请求时重置它。在点击每个链接(更改页面)时,调用检查信号量的方法,如果设置了信号,则该方法向用户提供上述警报。这样,在请求完成之前,用户将无法更改页面,并且您的请求被中止的问题将得到解决

希望这能回答这个问题。

答案 3 :(得分:0)

你会失败的。你没有回调回来。 Ajax响应将丢失。在这种情况下,我会在页面上放置一个阻止程序。这是非常常见的,以防止再次点击。阻止者只不过是“覆盖”整个浏览器的大面具。它也可能有一个等待图标。

答案 4 :(得分:0)

我前几天不得不处理同样的问题..似乎并没有那么复杂的处理..我们应该能够区分天气它的某种ajax错误或用户中止请求..当然我们没有从xhr对象获得特定事件..这就是为什么ajax错误带有异常... xhr对象和异常值的组合我们可以解决这个问题。

var message = '';
$('whatever').ajaxError(function(e, xhr, settings, exception) {
  // logic
   if (!xhr.status){
      if (exception=='abort'){
         message = 'User aborted AJAX request !'; 
      }
   }
}