#8084 closed bug (wontfix)
jsonp transport overrides dataType: json setting
Reported by: | anonymous | Owned by: | anonymous |
---|---|---|---|
Priority: | low | Milestone: | 1.next |
Component: | ajax | Version: | 1.5rc1 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
I upgrade my jquery lib from 1.5.b1 to 1.5.rc1. Now all my json ajax request don't work. I've got an "invalid label" error. (No problem with jquery 1.5.b1 or 1.4.4)
Change History (34)
comment:1 Changed 12 years ago by
Owner: | set to anonymous |
---|---|
Status: | new → pending |
comment:2 Changed 12 years ago by
Component: | unfiled → ajax |
---|---|
Priority: | undecided → low |
comment:3 Changed 12 years ago by
After some quick googling this blog post by Ben Nadel came up. Where he describes an issues related to evaluating json, in short doing eval( json )
and forgetting the parentheses, instead of eval( "(" + json ")" )
.
From this I made the following test case which triggers this exception. (not anymore as jsfiddle now returns the correct content type). You can this test case which uses a little trick to simulate the behavior for a missing dataType statement and the server returning the wrong content type.
How can this be fixed? Either by setting dataType: "json"
or by fixing the server to return the correct Content-Type
for json responses, which would be application/json
instead of application/javascript
.
So I guess your problem has a similar cause. You propably didn't specify the dataType: "json"
option on the ajax call and the server doesn't respond with the correct Content-Type
header.
What's still unclear to me is how what you have done worked, in 1.4.4 and 1.5b1 but not in 1.5rc1, because afaik there wasn't a change which could have triggered this issue. The test case I gave above triggers the exception with all 3 versions of jQuery (1.4.4, 1.5b1, 1.5rc1).
Thus it would be interesting to see a test case or more information by the reporter, detailing what exactly he does to trigger this in 1.5rc1 but not in 1.4.4 or 1.5b1.
Related reading:
comment:4 follow-up: 5 Changed 12 years ago by
I get the same label-error.
$.ajax({ url : _url, dataType : 'json', ifModified : true, success : function (data, status, xhr) { console.assert(typeof data === "object"); } }); ...
My Firebug shows me that the request is handled like dataType would be 'jsonp'. A callback is added to the url: "...?callback=jQuery1507447478875469641_1296513129436&_=1296513132903"
comment:5 Changed 12 years ago by
Replying to Simon:
I get the same label-error.
$.ajax({ url : _url, dataType : 'json', ifModified : true, success : function (data, status, xhr) { console.assert(typeof data === "object"); } }); ...My Firebug shows me that the request is handled like dataType would be 'jsonp'. A callback is added to the url: "...?callback=jQuery1507447478875469641_1296513129436&_=1296513132903"
Can you provide a test case for this? What does _url
look like?
comment:6 Changed 12 years ago by
Status: | pending → new |
---|
same error here with Jquery.1.5 release ... damned! I have a valid JSON data file confirmed by http://www.jsonlint.com/
comment:7 Changed 12 years ago by
I'm seeing the same issue. In my case the problem seems to be because I'm extending my ajax settings with the defaults(jQuery.ajaxSettings):
settings = jQuery.extend(settings, jQuery.extend({}, jQuery.ajaxSettings, settings));
At this point the default settings have been already been modified by jQuery during init, line 6896:
// Default jsonp settings jQuery.ajaxSetup({ jsonp: "callback", jsonpCallback: function() { return jQuery.expando + "_" + ( jsc++ ); } });
So when I call $.getJson with my extended settings jsonp and jsonpCallback are now set which causes the check for jsonp datatype to always succeed therefore treating the call as a jsonp call... line 6909:
if ( s.dataTypes[ 0 ] === "jsonp" || originalSettings.jsonpCallback || originalSettings.jsonp != null || s.jsonp !== false && ( jsre.test( s.url ) || dataIsString && jsre.test( s.data ) ) ) {
In my case the quick fix was to reset the jsonp and jsonpCallback back to null:
settings = jQuery.extend(settings, jQuery.extend({}, jQuery.ajaxSettings, settings)); settings.jsonp = null; settings.jsonpCallback = null;
I haven't spent too much time on this so not sure exactly why this is happening but if you're seeing ajax calls treated as jsonp calls this may be the reason and the above quick fix should work.
HTH Steve
comment:8 follow-up: 9 Changed 12 years ago by
"In my case the quick fix was to reset the jsonp and jsonpCallback back to null.". Confirmed.
// HACK: // jquery-1.5 sets up jsonp for all json ajax requests // undo the jsonp setting here so the json requests work again jQuery.ajaxSetup({ jsonp: null, jsonpCallback: null }); jQuery(function($) { // Do the rest of the application. $.ajax({ url: 'data', dataType: 'json', success: function() { console.log('success') }, error: function() { console.log('error') } }); });
comment:9 follow-up: 14 Changed 12 years ago by
Replying to anonymous:
"In my case the quick fix was to reset the jsonp and jsonpCallback back to null.".
In my case that works as well. Thanks!
// HACK: // jquery-1.5 sets up jsonp for all json ajax requests // undo the jsonp setting here so the json requests work again jQuery.ajaxSetup({ jsonp: null, jsonpCallback: null }); jQuery(function($) { // Do the rest of the application. $.ajax({ url: 'data', dataType: 'json', success: function() { console.log('success') }, error: function() { console.log('error') } }); });
comment:10 Changed 12 years ago by
Status: | new → pending |
---|---|
Summary: | ajax json → jsonp transport overrides dataType: json setting |
Please provide the URL that you are requesting and the URL of the page that is requesting it.
comment:11 Changed 12 years ago by
I'm seeing the same problem here. Our json is very simple:
{"estimatedCost":"0","wordCount":"137"}
comment:12 Changed 12 years ago by
same problem here. my quick fix was to wrap parentheses around my json and add the requesting callback on the server side. hope this is fixed in the next update
comment:13 Changed 12 years ago by
Status: | pending → new |
---|
same problem here. it was ok with jquery 1.4.2. Downloaded the 1.5 version and now appears "label error"
comment:14 Changed 12 years ago by
Replying to skywalker@…:
Replying to anonymous:
It works for me
jQuery.ajaxSetup({ jsonp: null, jsonpCallback: null});
but I wonder if its bug or feature ;)
"In my case the quick fix was to reset the jsonp and jsonpCallback back to null.".
In my case that works as well. Thanks!
// HACK: // jquery-1.5 sets up jsonp for all json ajax requests // undo the jsonp setting here so the json requests work again jQuery.ajaxSetup({ jsonp: null, jsonpCallback: null }); jQuery(function($) { // Do the rest of the application. $.ajax({ url: 'data', dataType: 'json', success: function() { console.log('success') }, error: function() { console.log('error') } }); });
comment:15 Changed 12 years ago by
what the line of the jquery.1.5.js did you added the line?
jQuery.ajaxSetup({ jsonp: null, jsonpCallback: null});
comment:16 Changed 12 years ago by
Some information:
- Nullifying jsonp and jsonpCallback using ajaxSetup as was suggested will break jsonp.
- jQuery.ajaxSettings is not documented and could very well end up not being exposed anymore in future versions.
- There are other things that will break if you extend your settings with ajaxSettings (context, contentType and all the options that are objects and that need to be deep-extended).
- Most of the time, you don't need to manually extend your own settings object using ajaxSettings prior to calling ajax since this is already done internally by ajax in a much safer way (with all the specificities of each option handled correctly for you).
- The rare cases where you need to have access to ajaxSettings is generally to control some custom options you set up there are defined when they're not in the settings object you wish to provide to ajax. In this situation, it's much simpler and efficient to do something like this:
( "myValue" in settings ? settings : ajaxSettings ).myValue;
and it has the advantage not to break anything. - Sometimes you wish to use your custom options and redefine (proxy) ajax to implement some additional behavior. In that case, I'd point you to prefilters: http://api.jquery.com/extending-ajax/#Prefilters and to the custom jQuery validation I recently made which provides a good example of how you'd feature detect jQuery 1.5 and use a prefilter or fall-back to proxying ajax for older versions: https://github.com/jaubourg/jquery-validation/blob/master/jquery.validate.js#L1084
Also, make sure your ajax requests fail without any plugin installed. Some plugins will proxy ajax and do it wrong.
comment:17 Changed 12 years ago by
I've been having the exact same problems listed above. This appears to be a bug in the most recent version of jquery validate that only manifests in 1.5. Ticket # 8064 is related: http://bugs.jquery.com/ticket/8064. I used the forked jquery.validate.js provided there and the problem went away, though using the .ajaxSetup method recommended above is less problematic.
comment:18 Changed 12 years ago by
The jquery.validate.js provided in ticket 8064 listed above works for me!!! Thanks!!!
comment:19 Changed 12 years ago by
Resolution: | → wontfix |
---|---|
Status: | new → closed |
I'll close this as wontfix. Let's mark all related present and future bugs as duplicate of this one and link to http://bugs.jquery.com/ticket/8084#comment:16 so that posters get a good picture of what's happening and how to properly fix their code.
comment:20 follow-up: 27 Changed 12 years ago by
I know this ticket is Closed. But I ran into the same Issue and want to share how I got that fixed. There's only one single thing (I can see) which was Changed in how jQuery requests JSONP. The Callback name.
jQuery 1.4.x requested like
/json/?jsoncallback=jsonp15108140517397602155
with jQuery 1.5.x this was changed to
/json/?jsoncallback=jQuery15108140517397602155_1299152711383&_=1299152711448
which wasn't recognized (due to the '_' in the Callback-Name) as a valid Callback - which of course was depending heavily on my Application providing the data.
Anyone else who has this: Open your Browser and do the request by hand. Once with and once without the underscore and see what you get back. May be the Server-Side won't get that parameter as a callback as well.
comment:24 follow-up: 26 Changed 12 years ago by
Please explain to me (you may need to use small words) why this is not a bug.
On line 15 of /ajax/jsonp.js, ajaxPrefilter() is decorated with "json jsonp" even though the comment on line 14 clearly states that the purpose of the pre filter is to normalize JSONP requests, not JSON requests.
This pre filter adds the callback query string which causes my app to issue a 302 upon receipt. It also adds an unnecessary callback function, which interferes with the processing of my JSON request. Finally, the suggestion in comment 16 does not help me, since the pre filter is processed AFTER the pre filter in /ajax/jsonp.js, when the damage is done.
Please fix /ajax/jsonp.js by removing "json" from the pre filter.
counsellorben
comment:26 Changed 12 years ago by
Replying to anonymous:
Please explain to me (you may need to use small words) why this is not a bug.
On line 15 of /ajax/jsonp.js, ajaxPrefilter() is decorated with "json jsonp" even though the comment on line 14 clearly states that the purpose of the pre filter is to normalize JSONP requests, not JSON requests.
This pre filter adds the callback query string which causes my app to issue a 302 upon receipt. It also adds an unnecessary callback function, which interferes with the processing of my JSON request. Finally, the suggestion in comment 16 does not help me, since the pre filter is processed AFTER the pre filter in /ajax/jsonp.js, when the damage is done.
Please fix /ajax/jsonp.js by removing "json" from the pre filter.
counsellorben
I suggest you actually read comment 16. Let me restate it, once again, anyway.
This behaviour (a json request being promoted as jsonp) can only occur if:
1) You provide the jsonp or jsonpCallback options or if your url contains one of the callback markers (=? or ??).
2) You use a plugin that redefines ajax and changes the options passed to the method in such a way that falls into case 1 (most of the time, by extending the options with ajaxSettings which is totally unnecessary and can even spawn nasty bugs, even in 1.4.4).
Would you be so kind as to try and remove the plugins you use then check your ajax requests. I guarantee you'll find the problem doesn't lie in 1.5 but in your application.
Yes, the prefilter is applied to jsonp AND json requests ON PURPOSE. This is actually what makes it possible to issue jsonp requests using getJSON with a url that contains one of the callback markers (=? or ??). The dataType of the request is "json", yet the prefilter has to be applied.
The only thing 1.5 changed is that the default jsonp and jsonpCallback options now sit in ajaxSettings. Those were the only two options not to be stored in this structure previously. Doing so exhibited faults into existing plugins and applications (mainly because people seem to believe it is somehow necessary to manually extend options with ajaxSettings while ajax does it internally -- and without caveats).
There's a lot of mis-conceptions in some of the presumed "solutions" to this ticket. If you actually take the time and read comment 16 carefully and stop presuming that the problem cannot possibly be on your side (because you see "json" somewhere in jQuery's code and are then convinced it's a blatant mistake while ignoring the fact jQuery has extensive unit tests regarding json requests that NEVER exhibit promotion to jsonp), then it will be a matter of seconds before you spot the problem in your application (or one of the plugins you use).
In short, stop presuming: look at your code and plugins.
Are those words numerous and small enough for you?
comment:27 follow-up: 29 Changed 12 years ago by
Replying to anonymous:
I know this ticket is Closed. But I ran into the same Issue and want to share how I got that fixed. There's only one single thing (I can see) which was Changed in how jQuery requests JSONP. The Callback name.
jQuery 1.4.x requested like
/json/?jsoncallback=jsonp15108140517397602155with jQuery 1.5.x this was changed to
/json/?jsoncallback=jQuery15108140517397602155_1299152711383&_=1299152711448which wasn't recognized (due to the '_' in the Callback-Name) as a valid Callback - which of course was depending heavily on my Application providing the data.
Anyone else who has this: Open your Browser and do the request by hand. Once with and once without the underscore and see what you get back. May be the Server-Side won't get that parameter as a callback as well.
What's the backend (server) you're using that won't recognize a callback name with an underscore as a valid javascript identifier?
I think it would be worth opening a new ticket for this one. If a broad server-side system has problem with underscores, it's pretty easy to have it removed (if it's a custom server-side script, that's another story).
comment:28 Changed 12 years ago by
I think, you must write about this hack in docs for jQuery, otherwise users will create duplicate issues (like me :-))
comment:29 Changed 12 years ago by
Replying to jaubourg:
What's the backend (server) you're using that won't recognize a callback name with an underscore as a valid javascript identifier?
I'm using Slim PHP Framework and an Application I wrote for that. An that App I used a regex which didn't match '_' as a valid character in a callback. Clearly my fault since I've written that in jQuery 1.4 times where the generated callback name did contain only a-z, A-Z & 0-9. So it was fine enough to match those. Now I simply return jsonp on my App in case the parameter 'jsoncallback' is set. In this case it was NOT a jQuery issue, but resulting in the same error ("invalid label" as outlines on the very first comment here).
comment:31 follow-up: 32 Changed 12 years ago by
I'm doing a "retry on error" attempt on $.ajax() call. I noticed it was appending &callback=jQuery[big_number_here]_[bigger_number] to my URL. It's weird, because it's automatically changing to jsonp, while the initial request is clearly JSON only. Then, I tried rewriting the dataType inside the 'error' callback to 'text json', and it appeared to fix it? I'm not even sure how this fixes it. jsFiddle: http://jsfiddle.net/g2VJZ/11/
comment:32 Changed 12 years ago by
Replying to anonymous:
I'm doing a "retry on error" attempt on $.ajax() call. I noticed it was appending &callback=jQuery[big_number_here]_[bigger_number] to my URL. It's weird, because it's automatically changing to jsonp, while the initial request is clearly JSON only. Then, I tried rewriting the dataType inside the 'error' callback to 'text json', and it appeared to fix it? I'm not even sure how this fixes it. jsFiddle: http://jsfiddle.net/g2VJZ/11/
the correct version is http://jsfiddle.net/g2VJZ/13/
comment:33 Changed 12 years ago by
We have had these problems, but we see different behavior between the min and non-min jquery versions.
comment:34 Changed 12 years ago by
it seems that the http://jsfiddle.net/g2VJZ/13/ works now as expected, changing to 1.6, and how this was set to wontfix and it got fixed? lol
This is not a useful bug report. Please follow the bug reporting guidelines or use the jQuery Forum for support requests.