5

We've encountered an odd problem with a $.getJSON call which only seems to affect older versions of IE. Code is as follows:

var success = function (response) {
     // do stuff
}

$.getJSON(url, success);

Under Chrome, Firefox, IE10, this code works just fine - getJSON hits the URL (which is valid, and is not cross domain), returns 200 OK and returns the data, which is passed through to the success function as you'd expect.

However under IE9 and below, the success callback is invoked but the response parameter passed through is undefined. By capturing the network traffic in IE Dev Tools I can see the call hitting the URL, returning 200 OK and returning valid JSON in the response body. So why is this coming out as undefined when it hits the success callback?

I've tried using the $.ajax call instead with appropriate parameters, and I see the same behaviour. Code below:

$.ajax({
    dataType: "json",
    url: url,
    success: success
};

We're using jQuery 1.7.2 (one of the libraries we've got on the page is broken under the newer version of jQuery, hence the old version).

EDIT: Just tried updating the page to use jQuery 1.10.1, doesn't fix the issue.

EDIT 2: I've confirmed that the JSON data being returned is valid via jsonlint.com so that isn't the issue either.

Henry Wilson
  • 3,281
  • 4
  • 31
  • 46
  • If you use a plain `XMLHttpRequest` does the same issue occur? – Qantas 94 Heavy Oct 23 '13 at 12:49
  • @Qantas94Heavy as in a call to $.ajax? I've just edited the question to include that - yeah I've tried using $.ajax, same behaviour – Henry Wilson Oct 23 '13 at 12:51
  • What is the data being returned? – Rory McCrossan Oct 23 '13 at 12:51
  • As in not using jQuery at all, but `$.ajax` should be fine in theory. Did you pass `dataType: "json"` to `$.ajax`? – Qantas 94 Heavy Oct 23 '13 at 12:51
  • No, I've not tried without jQuery, but that's not really an avenue I want to go down - the code in question forms a small part of a large script which is fairly heavily reliant on jQuery. I don't want to start doing manual AJAX calls in raw javascript. @RoryMcCrossan the data is a list of retailer objects in JSON. – Henry Wilson Oct 23 '13 at 12:53
  • $.ajax code included in the original question – Henry Wilson Oct 23 '13 at 12:55
  • @HenryWilson this is a little odd. I've got lots of AJAX calls which work fine in – Rory McCrossan Oct 23 '13 at 13:01
  • `success = function (response, txt, xhr) { console.log(xhr.responseText); }` Does that show what you expect? – epascarello Oct 23 '13 at 13:20
  • @RoryMcCrossan yep, it is odd, and odder still I believe this code has been working fine on IE9 and below for a while and it hasn't changed recently, just stopped working. It's not a whitespace issue, checked that/ – Henry Wilson Oct 23 '13 at 14:13
  • @epascarello xhr.responseText returns undefined in IE9 and lower. It contains the expected JSON data in Chrome, Firefox and IE10. – Henry Wilson Oct 23 '13 at 14:14
  • 1
    is your json definitely valid? IE is less forgiving on extra commas etc. double check your syntax by checking it in something like jsonlint.com. – royse41 Oct 23 '13 at 15:34
  • @seanxe jsonlint.com confirms it's valid JSON. I'd post it here as proof but it contains address/postcode data that I can't publicise. – Henry Wilson Oct 23 '13 at 15:36
  • There's an option in earlier IE versions to disable `XMLHttpRequest` - jQuery can use ActiveX instead but I don't know how it behaves if that option is enabled. – Alnitak Oct 23 '13 at 15:48
  • @HenryWilson that's cool. just thought i'd suggest that as i had that problem in the past. what's your content type set to on the page that returns the json? could you try 'application/json' ? – royse41 Oct 23 '13 at 15:52
  • @seanxe the data is coming from a .Net RESTful web service built using Nancy. The content type it returns is definitely application/json. Specifically in the IE Dev Tools under Response Headers it reads: Content-Type application/json; charset=utf8 – Henry Wilson Oct 23 '13 at 16:07
  • 1
    @HenryWilson are you using the IE browser tools or actual IE9? there's some known issues when using browser tools (the little drop down where you choose which version of IE you want) because the various modes IE provides have never really been full representations of older versions. if you can, fire up a VM or something and try from there. – royse41 Oct 23 '13 at 17:50
  • @seanxe actual IE9, i'm just going through the code in the dev tools for extra debug info. I know the "IE 9 mode" in IE10 doesn't actually amount to the same experience, particularly for javascript. – Henry Wilson Oct 23 '13 at 18:34
  • @HenryWilson cool - just trying to cover off all bases! i'll have a think and come back to you if i think of anything - good luck! – royse41 Oct 23 '13 at 19:57
  • How about defining the `success` callback inline, eg `$.getJSON(url, function(response) { ... });` ? – Phil Oct 24 '13 at 00:24
  • @Phil I can try that for a test but it's gonna prove a pain to rewrite the entire script this way (the code snippet is only part of a larger script). Is there any reason this would make a difference? – Henry Wilson Oct 24 '13 at 08:02

3 Answers3

1

If it is caching the result then set the cache to false before the request:

$.ajaxSetup({ cache: false });

If it is caching the result then use ajax instead of getJSON:

$.ajax({
    url: 'data.json',
    cache: false,
    dataType: 'json',
    success: function(data) {
        console.log('success', data);
    },
    error: function (request, status, error) {
        console.log('error', error);
    }
});

If the mime type is wrong then specify the dataType:

$.getJSON('data.json', 'json', function(data) {
    console.log('getJSON', data);
});

If the mime type is wrong then specify the dataType on the server:

header('Content-type: application/json');

If it's a variable conflict then rename your callback variable:

var success = function (newname) {
    console.log('success', newname);
}
$.getJSON(url, success);

If it's cross origin request then you can force jQuery to use it with:

$.support.cors = true;
Kim T
  • 5,770
  • 1
  • 52
  • 79
  • Tried all of these, nothing made any difference. I have noticed however that another call in the script using getJSON to a different service works fine, whereas another page which calls the same problematic service is also now not working under IE9, which leads me to suspect it's actually something server side. I'll report back if I ever find it... – Henry Wilson Oct 24 '13 at 10:04
  • See answer below, turned out this was to do with content types being returned by the server (though I'm still not 100% on what had changed or why IE was barfing at them). – Henry Wilson Oct 24 '13 at 10:39
1

Turns out this wasn't a jQuery issue whatsoever - it was something to do with the content-type headers being returned by the server. For whatever reason (still not clear exactly what changed to cause the issue) the media type being returned by the server (despite being plain old application/json) wasn't being interpreted properly by jQuery under the older versions of IE. I made a change to the server side code to return a vendor specific JSON content type and the code now works again.

EDIT: It occurs to me that one of the changes server side was an upgrade from version 0.17 to version 0.20 of the Nancy framework we use to serve the requests. I'm guessing this may have affected the headers in some subtle way, though I still haven't tracked down exactly how.

Henry Wilson
  • 3,281
  • 4
  • 31
  • 46
  • I'm having the same issue. It's terribly annoying. Could you be more specific on what a vendor specific JSON content type is? – user2483724 Apr 29 '14 at 22:04
  • 1
    @user2483724 vendor specific content types look like this: application/vnd.mycompany.mytype+json; version=1. You can use them to specify more explicitly the type of data being transmitted in context of your domain, and to version resources. There is more detail [here](http://stackoverflow.com/questions/13035169/versioning-rest-apis-and-vendor-specific-content-type), and loads more on the web – Henry Wilson May 05 '14 at 08:14
0

A little late to the game but I'll share my solution for anyone stumbling upon this thread:

I had the same issue, but the cause turned out to be a little different. I was passing tags to the getJSON url that contained special characters. Now Chrome silently converts these characters for me, but IE does not, which caused the server to return empty data.

theisof
  • 671
  • 6
  • 6