Bug Tracker

Opened 11 years ago

Last modified 10 years ago

#8653 closed bug

jQuery.param outputs "null" and "undefined" in the query string — at Version 15

Reported by: [email protected] Owned by:
Priority: low Milestone: 1.8
Component: ajax Version: 1.5.1
Keywords: 1.8-discuss Cc: dmethvin
Blocked by: Blocking:

Description (last modified by mikesherov)

This ticket is a followup to the discussion in http://forum.jquery.com/topic/should-null-be-passed-in-query-strings-generated-by-jquery-param where I am using jQuery.ajax to send data to a web service.

Given

jQuery.param({"string":"foo","null":null,"undefined":undefined})

the output is

"string=foo&null=null&undefined=undefined"

which the server will interpret as the strings "null" and "undefined" rather than as empty values.

My expected output would be:

"string=foo&null=&undefined"

where null values are coerced to empty string, and undefined values have no value. (This is the behaviour in Prototype 1.7, which seems reasonable.)

Change History (15)

comment:2 Changed 11 years ago by addyosmani

Thanks for submitting a ticket to the jQuery Bug Tracker!

In my opinion, the current behavior is correct and .param() should not be expected to automagically reassign values being passed to it. As per kboudloche, I too don't think the scenario referenced is something a lot of people run into either.

comment:3 Changed 11 years ago by jaubourg

Component: unfiledajax
Priority: undecidedlow

I beg to differ with addy here.

null and undefined are perfectly acceptable values for input data. Their meaning is quite obviously: "in the structure, yet empty"... and the only way to express that in a query string is with an empty parameter.

Current behaviour is not correct: a parameter with values null or undefined will be serialized the same as "null" or "undefined" (string) which is wrong imo.

Not sure I agree with the original poster regarding the solution... I would expect: string=foo&null. That way, people have a mean to prevent serialization (undefined) and a mean to transmit empty values (null).

While you can always pass an empty string, do we really want people to inspect their data structure prior to giving to serialize just to clean up nulls and undefineds and replace them with an empty string? Not sure I do knowing code calling serialize can have very good reasons to differentiate between null and "" internally.

comment:4 Changed 11 years ago by addyosmani

With respect to us expecting users to inspect their data structures prior to serialization, I don't think it's completely unreasonable but.. I'm all for making things as easy as possible to use. I could get down with a string=foo&null solution as jaubourg suggests.

Keeping this open for now to allow dmethvin an opportunity to comment. He was more closely tied in with the discussions on the forum and may have some further insights.

Last edited 11 years ago by addyosmani (previous) (diff)

comment:5 Changed 11 years ago by addyosmani

Status: newopen

comment:6 Changed 11 years ago by gnarf

This has returned this result for a LONG time and changing it would probably break somebody's application.

There was a stack overflow question http://stackoverflow.com/questions/1403963/getjson-call-with-null-parameters-to-mvc-controller-action/1404053#1404053 a while ago that has an answer equally applicable to "fixing" this bug for yourself. Nowadays you could probably even use an ajaxPrefilter (unless you are calling $.param() manually) .

In my opinion, it boils down to asking why you are passing null/undefined data as url parameters in the first place...

comment:7 Changed 11 years ago by addyosmani

Cc: dmethvin davemethvin added

CC'ing davemethvin for his thoughts in case he hasn't reviewed this as yet.

comment:8 Changed 11 years ago by [email protected]

When a property is set to undefined, hasOwnProperty still returns true, so I'm not sure about skipping them while writing out the query string.

Removing the = would cause me problems. I am calling an asp.net WebMethod which selects which handler to use based on keys in the query string, but it ignores parameters without an =. With the "string=foo&null" solution, a call to jQuery.ajax(webMethodUrl, { data : { key : value } }) may or may not call the web method at webMethodUrl, since the = might be missing. I would be back to checking each data object in ajaxPrefilter, and the change could break existing code.

Writing out empty string for null and undefined, "string=foo&null=&undefined=", would be safer.

comment:9 Changed 11 years ago by [email protected]

+1 for a change in this area. I have just bumped into this with a Java RESTful backend (Jersey) whereby the server side is expecting a UUID or null but it is getting a string of "null" or "undefined", both of which are a problem as it is sending a string instead of a null. From my point of view the fix is either:

  1. don't bother sending null values at all (on the basis that null = nothing to send).
  2. send "parameter="

The only workaround I have at the moment is to put null checks before pushing in each parameter which is very verbose.

comment:10 Changed 11 years ago by dmethvin

Cc: davemethvin removed
Keywords: 1.8=discuss added

Are there any fans of the current behavior? I suppose the problem is that none of them will arrive to defend it until we change it.

comment:11 Changed 11 years ago by dmethvin

Keywords: 1.8-discuss added; 1.8=discuss removed

comment:12 Changed 11 years ago by [email protected]

According to http://tools.ietf.org/html/rfc3986, the "%00" percent-encoding *could* be used. Nowhere does it say anything about using the string "null" for null values. Clearly, as URL is an encoding, the current behavior is broken.

comment:13 Changed 11 years ago by [email protected]

This behaviour is definitely not right. I'm sure many are eager to see it fixed.

For those interested, this is the part from SO answer that removes the properties that are set to null:

function stripNull(obj) {
  for (var i in obj) {
    if (obj[i] === null) delete obj[i];
  }
  return obj;
}

comment:14 Changed 11 years ago by Douglas <[email protected]…>

exxizt: stripNull removes null properties from an object, but jQuery.param should not modify the object passed in. The solution proposed by jaubourg in comment 3 still appears to be the correct one.

comment:15 Changed 11 years ago by mikesherov

Description: modified (diff)

+1, This makes sense, and I'm not sure who would rely on this buggy behavior.

Note: See TracTickets for help on using tickets.