Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fail callback called although Ajax request is performed and server returns 200 with data

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;
?>
like image 429
AndersTornkvist Avatar asked Feb 24 '12 12:02

AndersTornkvist


2 Answers

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.org')

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.

like image 184
Petr Vostrel Avatar answered Oct 17 '22 20:10

Petr Vostrel


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.

like image 27
MrE Avatar answered Oct 17 '22 20:10

MrE