【问题标题】:Ajax: How to prevent jQuery from calling the success event after executing xmlHttpRequest.abort();Ajax:如何防止jQuery在执行xmlHttpRequest.abort()后调用成功事件;
【发布时间】:2011-01-22 08:44:18
【问题描述】:

使用 jQuery 的 $.ajax() 函数。如果请求被故意中止,或者如果服务器关闭(没有响应),似乎会发生相同的结果;

这是在 xmlHttpRequest.status = 0xmlHttpRequest.readyState = 4 处触发的“成功”处理程序。

(我通过关闭 IIS 来模拟失败的请求,然后对已“关闭”的网站执行 xmlHttpRequest)

所以我的问题是如何确定中止请求或由于服务器未响应而真正失败的请求(因为服务器可能已关闭)之间的区别,因为这两种情况似乎都给了我相同的状态/就绪状态?

编辑 更准确地说,我想知道如何防止在 ajax 上调用 .abort() 函数后调用“成功”处理程序。

我已经重新措辞了这个问题以反映这一点。

【问题讨论】:

    标签: jquery xmlhttprequest


    【解决方案1】:

    您应该设置一个错误处理程序,如果请求失败,它将被调用。如果您想中止服务器上的请求,您可以只返回一些可以在成功处理程序中检查的值,或者您可以从服务器抛出异常。 jquery.ajax()

    编辑: 您可能想查看此 AJAX Queue/Cache/Abort/Block Manager v. 2.0 (link)。它将允许您在请求被中止后运行一个函数。

    【讨论】:

    • 请求没有在服务器上中止。它在客户端 JavaScript 中使用 xmlHttpRequest.abort() 中止。在我测试的两种情况下,错误处理程序都没有被触发,而是成功处理程序被触发,但状态/就绪状态为 0 和 4。
    • 抱歉,我不知道您在请求客户端调用 abort。我已编辑我的答案以提供更多帮助。
    • 谢谢。我已经尝试过了,它仍然不能解决我的问题。虽然它允许我注册代码来运行“onabort”,但它仍然会触发“success”事件。
    • 我尝试了您建议的“AJAX 队列/缓存/中止/块管理器”,但它似乎有问题。甚至在线演示都抛出错误(单击 3 秒延迟,然后“中止”)。无论如何,我最终编写了自己的队列管理器。我会将您的答案标记为已接受,因为它为我指明了正确的总体方向以达到我当前的解决方案。
    【解决方案2】:

    您可以在 xmlHttpRequest.abort 周围的包装器中单独跟踪中止。

    【讨论】:

      【解决方案3】:

      何时调用 abort。 我刚刚在firebug控制台中测试了以下

      var req = $.ajax({url:"localaddress", success:function(){alert("evil");}}); req.abort();
      

      请求后立即中止,不触发成功。

      【讨论】:

      • 每当用户多次点击页面上的特定按钮时都会调用它。这个想法是在开始一个新的请求之前,初始请求会被中止。你确定在你的例子中?也许你的错误处理程序被触发了,因为如果你发布到一个不存在/不工作的 URL?
      【解决方案4】:

      jQuery

      对于 jQuery

      var request = $.ajax( /* ... */ );
      
      // ...
      
      request.onreadystatechange = function () {};
      request.abort();
      

      所以,基本上我所做的就是在调用abort() 之前删除 success 回调处理程序。

      这就像一个魅力。

      jQuery >= 1.5:

      从 jQuery 1.5 开始,$.ajax(), $.get(), … 函数返回 jXHR 对象 (api documentation) 而不是 xmlHttpRequest 对象。因此,您不能简单地覆盖 xmlHttpRequest.onreadystatechange() 处理程序。

      这就是说,jXHR.abort() 负责不调用 success 回调处理程序。因此,调用jXHR.abort() 就足够了。

      您不一定需要更新以前的代码,因为将onreadystatechange 设置为jXHR 根本没有任何效果。

      长话短说,从 jQuery 1.5 开始,就可以了:

      var jxhr = $.ajax( /* ... */ );
      
      // ...
      
      jxhr.abort();
      

      【讨论】:

      • 谢谢,我要试一试。
      • 只有在你abort 之后才有效。如果您在再次调用jxhr 之前尝试abort,它将不起作用。
      • 谢谢,当 ajax 请求没有停止时,在使用旧 jquery 的旧网站上工作时,我绝对是疯了。
      【解决方案5】:

      我注意到了同样的行为,并且 request.onreadystatechange = function () {};在调用 .abort() 之前确实可以解决问题。

      【讨论】:

        【解决方案6】:

        只有一个请求的最佳解决方案是将 $.ajax 调用的返回值分配给一个变量,例如currentRequest,然后在您的success(data, responseCode, xhr) 函数中检查if(xhr == currentRequest),如果检查失败则提前返回。中止时,您只需将currentRequest 设置为null,这样检查就会失败。

        这样可以确保永远不会处理旧请求,这在您这样做时尤其重要,例如长轮询并在完成后立即重新启动请求(您真的不希望两个“轮询器”由于一个中止的请求启动一个新的请求而同时运行)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-19
          相关资源
          最近更新 更多