admin管理员组

文章数量:1384656

I have a HTML5 test webpage test.html with a cache manifest. The webpage does an Ajax request to the same server, to a webpage do_get_data.php that is listed under the section NETWORK: in the cache manifest.

The request is performed by both Firefox 10 and iPhone iOS 5 Safari (this is logged in the serving PHP script do_get_data.php). Firefox 10 calls the success callback function after 10 seconds, that is, when data from the server is returned. However, my iPhone iOS 5 Safari calls the fail callback function immediately after it started the request and doesn't call the success callback function.

For iPhone iOS 5 Safari, the textStatus is error and JSON.stringify(jqXHR) is {"readyState":0,"responseText":"","status":0,"statusText":"error"}.

The request is performed using the following code in 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" />

For reference, do_get_data.php looks like this:

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

I have a HTML5 test webpage test.html with a cache manifest. The webpage does an Ajax request to the same server, to a webpage do_get_data.php that is listed under the section NETWORK: in the cache manifest.

The request is performed by both Firefox 10 and iPhone iOS 5 Safari (this is logged in the serving PHP script do_get_data.php). Firefox 10 calls the success callback function after 10 seconds, that is, when data from the server is returned. However, my iPhone iOS 5 Safari calls the fail callback function immediately after it started the request and doesn't call the success callback function.

For iPhone iOS 5 Safari, the textStatus is error and JSON.stringify(jqXHR) is {"readyState":0,"responseText":"","status":0,"statusText":"error"}.

The request is performed using the following code in 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" />

For reference, do_get_data.php looks like this:

<?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;
?>
Share Improve this question asked Feb 24, 2012 at 12:07 AndersTornkvistAndersTornkvist 2,62921 silver badges38 bronze badges 7
  • What happens if you remove sleep(10) ? – a sad dude Commented Feb 27, 2012 at 23:04
  • And do I understand it correctly that you have a log that shows successful requests from Safari on the server side? – a sad dude Commented Feb 27, 2012 at 23:05
  • @asaddude Even if I remove sleep(10), the situation is the same. Yes, the log on the server side shows Safari. – AndersTornkvist Commented Feb 27, 2012 at 23:08
  • I see you use a hybrid definition of AJAX callbacks - new way (jqXHR.fail()) and the old way (success option of $.ajax()). Is there a particular reason for the bination? Does it yield same results when jqXHR.done() or error option respectively is used instead? – Petr Vostrel Commented Feb 28, 2012 at 17:45
  • @Petr There is no good reason for the bination. However, done() or error option do unfortunately not change the fact that it works in Firefox but not iOS 5 Safari. – AndersTornkvist Commented Feb 29, 2012 at 14:04
 |  Show 2 more ments

4 Answers 4

Reset to default 2 +25

I've been given to understand, that causes of status code 0 are (1) loading from file://, (2) unreachable network resource and (3) cross domain policy. Since you load PHP, we can safely rule number 1 and since your server logs Safari also the number 2 too, which leaves us with 3. Does all of the above code sit on the same domain? If not, use the Access-Control-Allow-Origin HTTP header in the PHP to allow cross domain requests.

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

Also, you should make sure, the click on the button input performs only the onclick and not any other default behavior (whatever that may be on the iOS). Returning false from the onclick handler would prevent it:

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

UPDATE:

As a last resort you can always simply disable the cache manifest to move its maybe buggy implementation out of the way.

I have struggled with this for a while and the answer was in the bug report answers:

use

NETWORK: *

in the cache manifest to avoid caching the ajax request too.

What if you change your $.ajax call to

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

Not sure how you are running your site under iOS, but there's been an issue with jQuery and AJAX requests while using manifest files: http://bugs.jquery./ticket/8412

Although you are already listing the resource under the NETWORK section of the manifest, I would suggest trying out the other workaround listed there:

jQuery.ajaxSetup({
  isLocal: true
});

本文标签: