Skip to main content

Bug Tracker

Side navigation

#9095 closed bug (wontfix)

Opened May 04, 2011 12:15PM UTC

Closed May 05, 2011 11:11PM UTC

jQuery 1.5 and above doesn't respect the dataFilter return type (it assumes it's always string when JSON is received)

Reported by: atodorov@infragistics.com Owned by: jaubourg
Priority: low Milestone: 1.6.1
Component: ajax Version: 1.5
Keywords: Cc:
Blocked by: Blocking:
Description

in jQuery 1.4.*, (more precisely, 1.4.4) this is the part of the httpData code:

The filter can actually parse the response

if ( typeof data === "string" ) {

Get the JavaScript object, if JSON is used.

if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {

data = jQuery.parseJSON( data );

// If the type is "script", eval it in global context

} else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {

jQuery.globalEval( data );

}

}

return data;

So, it knows that "the filter can actually parse the response".

But in 1.5 > , especially this is from 1.6, that's what happens:

parseJSON: function( data ) {

if ( typeof data !== "string" || !data ) {

return null;

}

So the code doesn't respect the return type of the dataFilter. it always assumes it's going to be string. It should not return null, but just the data object. That's the fix. To me this is a breaking change since it works in all previous jQuery versions.

Thank you,

Angel

Attachments (0)
Change History (4)

Changed May 04, 2011 12:20PM UTC by atodorov@infragistics.com comment:1

looks like a duplicate of:

http://bugs.jquery.com/ticket/8267

Thank you,

Angel

Changed May 04, 2011 12:24PM UTC by anonymous comment:2

Actually the other bug hasn't been fixed. Could you guys consider fixing this? The fix is really simple. Just don't return null.

Thanks,

Angel

Changed May 05, 2011 01:58PM UTC by dmethvin comment:3

component: unfiledajax
milestone: 1.next1.6.1
owner: → jaubourg
priority: undecidedblocker
status: newassigned

The other bug wasn't fixed because the original reporter didn't provide enough detail.

Changed May 05, 2011 11:11PM UTC by jaubourg comment:4

priority: blockerlow
resolution: → wontfix
status: assignedclosed

1.5+ is less lenient when it comes to data format but the fact is dataFiltering text and returning json in the context of a request of dataType "json" is simply plain wrong. The text to json converter should throw an error rather than return null given that it expects *text* as its input.

I actually do consider this a bug... in 1.4.

If you wanna parse text than it's quite obvious you ought to make a request of dataType "text", not "json" (what's the intent behind using the json dataType if the converter is not to be used?). If you use "text" as the dataType, everything will, of course, work as expected. However, if you're using the "json" dataType then the dataFilter is expected to handle some text *and* return some other text... so that text to json conversion can occur (think data pre-cleaning).

Keep in mind 1.5+ generalizes the conversion system in ajax and you can chain dataTypes so if you had "text dataType1 dataType2 dataType3", what should jQuery do? Bypass all the converters, making it impossible to properly validate data or to use dataFiler as a data cleaner (since you would have to duplicate the whole conversion logic)?

So, if you want to parse text as json yourself with a dataFiler, use dataType "text": it'll work in 1.4 too. Better yet, use the 1.5 converters option and do something like this:

$.ajax( url, {
  converters: {
    "text json": yourCustomParser
  }
});

If you want to override text to json conversion globally using ajaxSettings (so that getJSON would use it) -- I don't recommand it but I'd like to show it's still perfectly feasible and much safer in 1.5 -- it's pretty easy to feature detect 1.5 and do it for older and newer versions alike:

$.ajaxSetup(
  $.ajaxTransport ? {
    converters: {
      "text json": yourCustomParser
    }
  } : {
    dataFilter: yourCustomParser
  }
);

Thing is the converters approach won't break non-json requests, the dataFilter one will since it'll be applied to all requests regardless of their dataType.