Bug Tracker

Opened 8 years ago

Closed 8 years ago

#9095 closed bug (wontfix)

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@… 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

Change History (4)

comment:1 Changed 8 years ago by atodorov@…

looks like a duplicate of:

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

Thank you, Angel

comment:2 Changed 8 years ago by anonymous

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

comment:3 Changed 8 years ago by dmethvin

Component: unfiledajax
Milestone: 1.next1.6.1
Owner: set to jaubourg
Priority: undecidedblocker
Status: newassigned

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

comment:4 Changed 8 years ago by jaubourg

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.

Note: See TracTickets for help on using tickets.