Skip to main content

Bug Tracker

Side navigation

#8653 closed bug (fixed)

Opened March 26, 2011 01:01PM UTC

Closed May 16, 2012 06:04PM UTC

jQuery.param outputs "null" and "undefined" in the query string

Reported by: d@3vq.net Owned by:
Priority: low Milestone: 1.8
Component: ajax Version: 1.5.1
Keywords: 1.8-discuss Cc: dmethvin
Blocked by: Blocking:
Description

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.)

Attachments (0)
Change History (29)

Changed March 26, 2011 01:05PM UTC by d@3vq.net comment:1

Working example: http://jsfiddle.net/YuWXy/

Changed March 26, 2011 03:24PM UTC by addyosmani comment:2

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.

Changed March 26, 2011 03:39PM UTC by jaubourg comment:3

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.

Changed March 26, 2011 04:02PM UTC by addyosmani comment:4

_comment0: That's alright :) \ \ 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. 1301176933246321

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.

Changed March 26, 2011 09:12PM UTC by addyosmani comment:5

status: newopen

Changed March 26, 2011 10:21PM UTC by gnarf comment:6

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...

Changed March 27, 2011 11:51PM UTC by addyosmani comment:7

cc: → dmethvin, davemethvin

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

Changed March 28, 2011 01:01PM UTC by d@3vq.net comment:8

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.

Changed July 07, 2011 11:04AM UTC by oliver.dungey@gmail.com comment:9

+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.

Changed October 07, 2011 03:05AM UTC by dmethvin comment:10

cc: dmethvin, davemethvindmethvin
keywords: → 1.8=discuss

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.

Changed October 07, 2011 03:05AM UTC by dmethvin comment:11

keywords: 1.8=discuss1.8-discuss

Changed October 19, 2011 11:20PM UTC by smart@prescreen.com comment:12

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.

Changed November 23, 2011 10:36PM UTC by exxizt@gmail.com comment:13

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;
}

Changed November 24, 2011 05:47PM UTC by Douglas <rampant@gmail.com> comment:14

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.

Changed December 13, 2011 01:37PM UTC by mikesherov comment:15

description: 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.) \ \ 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.)\ \

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

Changed December 13, 2011 03:59PM UTC by jaubourg comment:16

+1, we just need to iron out what the fix is (see my comment #3). Current behaviour doesn't make sense and I shudder to think who would rely on it.

Changed December 13, 2011 05:04PM UTC by dmethvin comment:17

description: 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.)\ \ 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.) \ \

+1, I am not a fan of the current behavior. I think we should totally skip undefined values and use "name=" for the null case.

Changed December 13, 2011 05:27PM UTC by jzaefferer comment:18

description: 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.) \ \ 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.)\ \

+1

Changed December 14, 2011 04:00PM UTC by timmywil comment:19

+1

Changed December 19, 2011 05:12PM UTC by rwaldron comment:20

description: 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.)\ \ 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.) \ \

+0, I've never experienced an issue with this... wouldn't it break BC?

Changed February 12, 2012 01:36PM UTC by sindresorhus comment:21

#11329 is a duplicate of this ticket.

Changed February 13, 2012 10:01PM UTC by wardrop comment:22

By my duplicate ticket above, I clearly agree. The only types a controller for a web application should care about, is String - there's no place or need for sending the variable state, plus it means any server-side passing of null and undefined values would mean that any user that inputs these string values ("null" and "undefined") would not get the result they expected. An empty string communicates a undefined/null/empty/default value. The exact meaning of an empty string depends on the controller that handles it.

I think not fixing for the sake of backwards compatibility is a poor excuse. First of all, I'm of the opinion that anyone that depends on this behaviour ought to have their application break (nasty, I know), but more importantly, no one should be upgrading jQuery on a production application and expect it to work every time. The sooner this is changed, the less of a pain it will be in the future.

In the meantime, I've overridden the built-in encodeURIComponent function to return empty strings for null and undefined. This is what jQuery uses that results in the "null" and "undefined" strings.

Changed February 14, 2012 12:15AM UTC by Douglas <rampant@gmail.com> comment:23

Array.prototype.join sets a precedent for treating null and undefined as empty strings while serialising a structure to a string (EMCA spec 15.4.4.5). The param utility should behave in the same way since the use case is so similar.

The trade off on the receiving end is either to be able to distinguish null and undefined, or to be able to distinguish null from the string "null". The latter appears to be more useful.

Changed February 14, 2012 12:18AM UTC by dmethvin comment:24

milestone: 1.next1.8

I'm not sure why there's so much activity on this ticket now. The ticket is open and has been voted for action in 1.8. There is no need for further discussion on this unless you are one of these people and want to retain the current behavior.

Changed March 23, 2012 07:25PM UTC by tks2103 comment:25

submitted pull request for behavior as outlined in comment 3:

https://github.com/jquery/jquery/pull/714

Changed March 23, 2012 07:48PM UTC by rwaldron comment:26

On github you also cited http://bugs.jquery.com/ticket/8653#comment:17 - so which is it? The missing = just looks odd, as it breaks the notion of key = val. Especially in this context:

foo=bar&baz&huh=what-the

Changed March 23, 2012 07:52PM UTC by tks2103 comment:27

reasoning for "key" over "key=" in the null case is that "key=" does not distinguish empty string from null case. thats why i favored "key".

Changed March 23, 2012 08:12PM UTC by dmethvin comment:28

I discussed with tks2103 and we're just going to turn null/undefined into empty strings, the behavior advocated by @Douglas above. It's the simplest and smallest to implement. Trying to distinguish between special values is not advisable, the main use case of jQuery.param is to take a form element value and serialize it, these cases are not defined.

Changed May 16, 2012 06:04PM UTC by tsinha comment:29

resolution: → fixed
status: openclosed

Fix #8653, .param() undefined/null values become empty strings

Changeset: 36d2d9ae937f626d98319ed850905e8d1cbfd078