【问题标题】:Fail callback called although Ajax request is performed and server returns 200 with data尽管执行了 Ajax 请求并且服务器返回 200 和数据,但调用失败回调
【发布时间】:2014-07-11 06:24:13
【问题描述】:

我有一个带有缓存清单的 HTML5 测试网页 test.html。该网页向同一服务器发出 Ajax 请求,向缓存清单中 NETWORK: 部分下列出的网页 do_get_data.php 发出请求。

该请求由 Firefox 10 和 iPhone iOS 5 Safari 执行(这记录在服务 PHP 脚本 do_get_data.php 中)。 Firefox 10 在 10 秒后调用success 回调函数,即从服务器返回数据时。但是,我的 iPhone iOS 5 Safari 在启动请求后立即调用了fail 回调函数,并且没有调用success 回调函数。

对于 iPhone iOS 5 Safari,textStatuserrorJSON.stringify(jqXHR){"readyState":0,"responseText":"","status":0,"statusText":"error"}

使用test.html中的以下代码执行请求:

<script type="text/javascript">
    function test_ok(data) {
        alert('Test OK, data: ' + JSON.stringify(data));
    }
    function testFail(jqXHR, textStatus) {
        alert(textStatus + ' | ' + JSON.stringify(jqXHR));
    }
    function get_data(testurl) {
        var senddata, request;
        alert('Request for ' + testurl + ' started.');
        window.testid = new Date().getTime();
        senddata = {
            background: true,
            requestId: window.testid
        };
        request = $.ajax({
            url: testurl,
            cache: false,
            type: "GET",
            data: senddata,
            success: test_ok
        });
        request.fail(testFail);
    }
</script>
<input type="button" onclick="get_data('do_get_data.php')" value="test sending" />

作为参考,do_get_data.php 看起来像这样:

<?php
    $id = md5(rand() . rand());
    trigger_error(implode("\t", array('start', $id, $_SERVER['REQUEST_URI'], $_SERVER['REMOTE_ADDR'], $_SERVER['USER_AGENT']));
    sleep(10);
    header('Content-Type: application/json');
    $json = json_encode(array('msg'=>'Test was OK'));
    trigger_error(implode("\t", array('echo', $id, $json));
    echo $json;
?>

【问题讨论】:

  • 如果你删除 sleep(10) 会发生什么?
  • 我是否理解正确,您有一个日志显示服务器端来自 Safari 的成功请求?
  • @asaddude 即使我删除了 sleep(10),情况也是一样的。是的,服务器端的日志显示的是 Safari。
  • 我看到您使用 AJAX 回调的混合定义 - 新方式 (jqXHR.fail()) 和旧方式 ($.ajax()success 选项)。组合有什么特别的原因吗?当分别使用jqXHR.done()error 选项时,是否会产生相同的结果?
  • @Petr 没有充分的理由进行组合。但是,done()error 选项很遗憾不会改变它在 Firefox 中有效但在 iOS 5 Safari 中无效的事实。

标签: javascript jquery ajax html cache-manifest


【解决方案1】:

我已经了解到,状态码 0 的原因是 (1) 从 file:// 加载,(2) 无法访问的网络资源和 (3) 跨域策略。由于您加载了 PHP,我们可以安全地统治数字 1,并且由于您的服务器也记录 Safari 的数字 2,因此我们只剩下 3。以上所有代码是否都位于同一个域中?如果没有,请在 PHP 中使用Access-Control-Allow-Origin HTTP 标头来允许跨域请求。

header('Access-Control-Allow-Origin: http://example.org')

此外,您应该确保单击按钮输入仅执行onclick 而不是任何其他默认行为(无论在 iOS 上可能是什么)。从 onclick 处理程序返回 false 会阻止它:

<input type="button" onclick="get_data('do_get_data.php'); return false" ... />

更新:

作为最后的手段,您始终可以简单地禁用缓存清单,以将其可能存在错误的实现移开。

【讨论】:

  • 非常感谢您的回答。我喜欢你的推理。从理论上讲,我同意这可能是一个跨域策略问题。但是,它位于同一个域中。 http:// 甚至没有用于 URL,而是 do_get_data.php 没有任何域名。有没有调试这个问题的好方法?返回 false 实际上并没有改变任何东西。
  • 不幸的是,iOS 和移动设备上的调试工具通常很差......在进行研究时,我还偶然发现了相关提及,其中相对路径被确定为原因。您是否尝试过绝对 URL 路径?并且澄清一下 - 如果没有缓存清单,问题是否仍然存在?
  • 但是,使用您在之前的评论中建议的禁用清单。在我找到真正的罪魁祸首之前,这是一个不错的解决方法。如果您只是将您的评论复制到新答案中,或者将您的评论包含在此答案中,我会在没有其他人解决主要问题的情况下为您提供赏金。
  • @Richard86 我已经更新了答案,我很高兴它为你消除了痛苦。但是,由于我们现在以某种方式将其隔离,出于好奇,您的缓存清单看起来如何?
【解决方案2】:

我已经为此苦苦挣扎了一段时间,答案在错误报告答案中:

使用

网络: *

在缓存清单中以避免缓存 ajax 请求。

【讨论】:

    【解决方案3】:

    如果您将$.ajax 呼叫更改为

    $.ajax({
        url: testurl,
        cache: false,
        type: "GET",
        data: senddata
    }).then(
        function(result) { test_ok(result); },
        function(result) { testFail(result); }
    );
    

    【讨论】:

    • 感谢您的回答。不幸的是,这并不能解决问题。它仍然会产生一个请求,但会调用 testFail()
    • 如果您删除 PHP 代码中的 Content-Type 标头会发生什么?也许 Safari 对此有疑问。在我编写的所有 AJAX 代码中,我从未设置过 Content-Type 标头。我只是回显纯文本。
    【解决方案4】:

    不确定您如何在 iOS 下运行您的网站,但在使用清单文件时出现 jQuery 和 AJAX 请求问题:http://bugs.jquery.com/ticket/8412

    虽然您已经在清单的 NETWORK 部分下列出了资源,但我建议尝试那里列出的其他解决方法:

    jQuery.ajaxSetup({
      isLocal: true
    });
    

    【讨论】:

    • 感谢您对这个问题的新想法。似乎票实际上返回了正确的内容,但对我来说并非如此。该请求实际上是在服务器上实时完成的。我尝试使用isLocal: true,但不幸的是这并没有解决问题。存在同样的错误。
    猜你喜欢
    • 2017-06-04
    • 2015-06-22
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    • 2019-12-16
    • 2018-08-23
    • 1970-01-01
    相关资源
    最近更新 更多