9

Hello I noticed that this simple code doesn't work the way it is supposed to work...

    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);
        }
    });
}

The test has been run on localhost, I mean: I load the page, I shut down the local webserver, then I fire the request (via a simple button with onclick pointing to this function). Error doesn't ever get called, what I get is to have the success handler called and it has textStatus = "success" and data = null. I even notice that the request times out long before 10 seconds. This happens on Firefox (last version), Chrome (last version) and Safari 5. Why this? Is it due to the fact I'm working on localhost?


I forgot to tell: THE Request isn't cached. In fact both firebug and Chrome dev tools show the request to fail.


Big update

This behaviour is related to the use of localhost. In fact if I load this page from another collegue PC and before triggering the request I disconnect my PC from the network, I correctly get the error handler fired with timeout as status. I think this is a bug of jQuery. It will make me hard to test the timeout errors :(


Guys from jQuery forums say this is due to the way the network stack aborts the connection, given that the host is localhost. I tested this on Windows 7 only. If you feel like testing this on other systems and you can work out some jQuery internals, report to this post at the jQuery forums:

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

gotch4
  • 13,093
  • 29
  • 107
  • 170
  • 2
    Why do you have `'url'` and `'dataType'` quoted as strings? – Codesleuth Sep 01 '10 at 10:00
  • I tried to remove quotes: no difference – gotch4 Sep 01 '10 at 10:02
  • Can you show a demo page for this? – Nalum Sep 01 '10 at 10:14
  • @Codesleuth. "url" and "dataType" must be quoted to be a valid JSON object. It also allows you to use reserved keywords like "this", "true", "undefined", etc as the name of the property. Now, I know what the OP posted isn't really JSON...but it is valid none-the-less. I actually prefer quoted properties in my JS objects. – David Murdoch Sep 01 '10 at 18:20
  • And on that note...@gotch4: you really should try to get in the habit of either exclusively using single quotes (`'`) or double (`"`) in your code. It makes it more comfortable to read. You should also either use quotes around the property names of your JS object or not...this mix and match stuff just looks bad. :-) I recommend using single quotes to save you from having to `Shift + ' = "` every time you type a string. – David Murdoch Sep 01 '10 at 18:24
  • 1
    @David Murdoch I think you missed my point. Only two property names are quoted - I was enquiring to ascertain why it wasn't uniform practice across the code. – Codesleuth Sep 02 '10 at 08:07
  • The reason of this mixed habit is that, well, it's a bad habit! This has nothing to do with the problem above anyway, see my response down there. – gotch4 Sep 02 '10 at 09:00

3 Answers3

8

UPDATED: Try to replace the test (data == null) to the (XMLHttpRequest.readyState === 4 && XMLHttpRequest.status === 0).

In W3C Candidate Recommendation about XMLHttpRequest standard is described that it must exist so named "error flag" which should be used to indicates some type of network error or abortion. In case of such kind of errors the status in the XMLHttpRequest will be 0 instead of 200 ("OK"), 201 ("Created"), 304 ("Not Modified") and so on. To be exactly corresponds to http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute the XMLHttpRequest.status can be 0 in case of XMLHttpRequest.readyState equal to 0 or 1 ("UNSENT" or "OPENED"). Another case is XMLHttpRequest.readyState equal to 4 ("DONE") and "error flag" is true. If we have no from these two cases the XMLHttpRequest.status must be a HTTP status code. Under http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html or http://www.w3.org/Protocols/HTTP/1.0/spec.html#Status-Codes there are no HTTP status code equal to 0. So it seems to my that you can do following

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");
            }
        }
    });
});
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Thanks, this sounds more robust. Anyway I posted all this in jQuery forums and some dev started caring about this. I even sent some debug logs and probably this thing will be fixed. – gotch4 Sep 02 '10 at 09:02
  • @gotch4: I couldn't find your post in jQuery bug reports. Could you post the reference? I found some other close reports like http://dev.jquery.com/ticket/6060. It seems that the change http://dev.jquery.com/changeset/6432 which try to make a workaround for Opera was wrong implemented and work wrong now in case XMLHttpRequest.status=0 in other browsers. If you not do this. I'll recoment you to insert in your bug report the reference http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute. The code of jQuery should at least follow standards and then try to implement any workaround. – Oleg Sep 02 '10 at 14:38
1

If there's a network error the success callback will be called and not the error even if it doesn't make much sense. Checkout this blog post for details. So basically what you've done by checking data == null is correct.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Please look at my answer and code examples. How you interpret the results? Do you think that we have a bug in jQuery? – Oleg Sep 01 '10 at 13:29
  • No, your test is wrong: you are changing the port number. This is not allowed due to Same Origin Policy restrictions: http://en.wikipedia.org/wiki/Same_origin_policy. You cannot perform AJAX queries if you change the port number. – Darin Dimitrov Sep 01 '10 at 14:19
  • You are right, that my first example should be interpret as Same "Origin Policy restrictions" error. I write new version of the code based on http://www.w3.org/TR/XMLHttpRequest, which seems to me can detect an error in both cases: "Origin Policy restrictions" or any kind on network errors. In all this cases the call of "success" handler should be interpret as an error. What do you think about this suggestion? – Oleg Sep 01 '10 at 18:13
-2

Even if you shut down the local server, it should still be able to see the json file.. try to remove the file temporarily and see if that works.

A. M.
  • 580
  • 1
  • 8
  • 21
  • If I remove the file and the server is ON, of course I get a 404 and the error handler fires. If I remove the file and the server is OFF, same result. – gotch4 Sep 01 '10 at 10:14