【问题标题】:jQuery $.ajax, error handler doesn't workjQuery $.ajax,错误处理程序不起作用
【发布时间】:2011-04-06 17:16:45
【问题描述】:

你好,我注意到这个简单的代码并没有按照它应该的方式工作......

    function test() {
    $.ajax( {
        'url' : 'test/GameConfiguration.json',
        'dataType' : 'json',
        data : {
            a : 'aaa'
        },
        cache : false,
        method : 'get',
        timeout : 10000, //10 secs of timeout 
        success : function(data, textStatus, XMLHttpRequest) {
            console.log("success");
            if (data == null)
                console.log("it's not a real success");
        },
        error : function(XMLHttpRequest, textStatus, errorThrown) {
            console.log("error: " + textStatus);
        }
    });
}

测试已经在本地主机上运行,​​我的意思是:我加载页面,我关闭本地网络服务器,然后我触发请求(通过一个简单的按钮,onclick 指向这个函数)。永远不会调用错误,我得到的是调用成功处理程序,它有 textStatus = "success" 和 data = null。我什至注意到请求在 10 秒之前就超时了。 这发生在 Firefox(最新版本)、Chrome(最新版本)和 Safari 5 上。为什么会这样?是因为我在 localhost 上工作吗?


我忘了说:请求没有被缓存。事实上,firebug 和 Chrome 开发工具都显示请求失败。


重大更新

此行为与 localhost 的使用有关。事实上,如果我从另一台同事 PC 加载此页面,并且在触发请求之前我断开我的 PC 与网络的连接,我正确地得到了错误处理程序,并以超时作为状态触发。我认为这是 jQuery 的一个错误。这会让我很难测试超时错误:(


来自 jQuery 论坛的人说这是由于网络堆栈中止连接的方式,因为主机是 localhost。我仅在 Windows 7 上对此进行了测试。如果您想在其他系统上进行测试,并且可以解决一些 jQuery 内部问题,请在 jQuery 论坛上报告此帖子:

http://forum.jquery.com/topic/strange-and-unexpected-behaviour-of-ajax-error-and-localhost#14737000001331961

【问题讨论】:

  • 为什么将'url''dataType' 引用为字符串?
  • 我尝试删除引号:没有区别
  • 你能展示一个演示页面吗?
  • @Codesleuth。必须引用“url”和“dataType”才能成为有效的 JSON 对象。它还允许您使用“this”、“true”、“undefined”等保留关键字作为属性名称。现在,我知道 OP 发布的内容并不是真正的 JSON……但它仍然是有效的。我实际上更喜欢在我的 JS 对象中引用属性。
  • @David Murdoch 我想你没抓住我的意思。只引用了两个属性名称 - 我正在询问为什么它不是跨代码的统一做法。

标签: jquery ajax timeout


【解决方案1】:

更新:尝试将测试(data == null) 替换为(XMLHttpRequest.readyState === 4 && XMLHttpRequest.status === 0)

在关于XMLHttpRequest 标准的 W3C 候选推荐中描述了它必须存在,因此命名为“错误标志”,它应该用于指示某种类型的网络错误或中止。如果出现此类错误,XMLHttpRequest 中的状态将为 0 而不是 200(“OK”)、201(“已创建”)、304(“未修改”)等等。要与http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute 完全对应,XMLHttpRequest.status 可以为 0,以防XMLHttpRequest.readyState 等于 0 或 1(“未发送”或“已打开”)。另一种情况是XMLHttpRequest.readyState 等于 4(“DONE”)并且“错误标志”为真。如果这两种情况都没有,XMLHttpRequest.status 必须是 HTTP 状态代码。在http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.htmlhttp://www.w3.org/Protocols/HTTP/1.0/spec.html#Status-Codes 下没有等于0 的HTTP 状态代码。所以在我看来,您可以执行以下操作

jQuery(document).ready(function () {
    $.ajax({
        type: 'GET',
        url:  'test/GameConfiguration.json',
        dataType: 'json',
        cache : false,
        success: function(data, textStatus, xhr){
            if (xhr.readyState === 4 && xhr.status === 0) {
                // if readyState is DONE (numeric value 4) then corresponds to
                // http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-done
                // "The DONE state has an associated error flag that indicates
                // some type of network error or abortion."
                // Corresponds to http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute
                // If error flag it true, xhr.status is 0.
                alert('"error flag\" is true. It means that we have a network error"+
                      " or abortion (for example because of Same Origin Policy restrictions)');
            }
            else {
                alert(textStatus);
                alert(data);
            }
        },
        error: function(xhr, textStatus, errorThrown) {
            if (textStatus !== null) {
                alert("error: " + textStatus);
            } else if (errorThrown !== null) {
                alert("exception: " + errorThrown.message);
            }
            else {
                alert ("error");
            }
        }
    });
});

【讨论】:

  • 谢谢,这听起来更健壮。无论如何,我在 jQuery 论坛上发布了所有这些内容,一些开发人员开始关心这个问题。我什至发送了一些调试日志,可能这个问题会得到修复。
  • @gotch4:我在 jQuery 错误报告中找不到您的帖子。你能发布参考吗?我发现了一些其他接近的报告,例如dev.jquery.com/ticket/6060。似乎尝试为 Opera 制定解决方法的更改 dev.jquery.com/changeset/6432 实施错误并且现在在其他浏览器中 XMLHttpRequest.status=0 的情况下工作错误。如果你不这样做。我会建议您在错误报告中插入参考w3.org/TR/XMLHttpRequest/#the-status-attribute。 jQuery 的代码至少应该遵循标准,然后尝试实现任何变通方法。
【解决方案2】:

如果出现网络错误,将调用success 回调而不是error,即使它没有多大意义。结帐this blog post 了解详情。所以基本上你通过检查data == null所做的事情是正确的。

【讨论】:

  • 请看我的答案和代码示例。你如何解释结果?您认为我们在 jQuery 中存在错误吗?
  • 不,您的测试是错误的:您正在更改端口号。由于同源策略限制,这是不允许的:en.wikipedia.org/wiki/Same_origin_policy。如果更改端口号,则无法执行 AJAX 查询。
  • 你是对的,我的第一个例子应该被解释为相同的“源策略限制”错误。我基于w3.org/TR/XMLHttpRequest 编写了新版本的代码,在我看来,这两种情况下都可以检测到错误:“源策略限制”或任何类型的网络错误。在所有这些情况下,“成功”处理程序的调用应被解释为错误。你觉得这个建议怎么样?
【解决方案3】:

即使你关闭本地服务器,它应该仍然能够看到 json 文件。尝试暂时删除该文件,看看是否有效。

【讨论】:

  • 如果我删除文件并且服务器处于开启状态,我当然会得到 404 并且错误处理程序会触发。如果我删除文件并且服务器处于关闭状态,则结果相同。
猜你喜欢
  • 2020-08-19
  • 1970-01-01
  • 2013-01-04
  • 2011-05-23
  • 1970-01-01
  • 2013-06-02
  • 2015-03-18
  • 2012-02-25
  • 2011-03-25
相关资源
最近更新 更多