Side navigation
#4201 closed feature (fixed)
Opened February 20, 2009 02:10PM UTC
Closed December 05, 2009 01:52AM UTC
Improved $.param serialization
Reported by: | john | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | 1.4 |
Component: | ajax | Version: | 1.3.2 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
I've been using it a lot with a Ruby on Rails backend, and one of the
things I need was a way to nest params like the way Rails handles
forms/objects, eg. with a Page object:
page[name]=Foo&page[author]=Bar
Unfortunately, $.param didnt translate objects this way, but adding
just a few simple lines made it work like a charm:
Now:
$.param({page: {name: 'Foo', author: 'Bar'})
Translates to above.
Thought this might be helpful for other people working with Rails/
jQuery and with a little clean up could be a nice addition to core.
Attachments (0)
Change History (6)
Changed September 02, 2009 05:17AM UTC by comment:1
resolution: | → fixed |
---|---|
status: | new → closed |
Changed September 03, 2009 02:50AM UTC by comment:2
resolution: | fixed |
---|---|
status: | closed → reopened |
I was working on writing the deserialization code for this change into URL Utils this evening, but came across a potential problem.
This scenario is ambiguous at best, but a total mess at worst:
console.log( decodeURIComponent( $.param( { a: [ 1, 2, { b: 3, c: 4 } ] } ) ) );
That outputs a=1&a=2&a[b]=3&a[c]=4 which when deserialized, would probably yield an 'a' param that is an array [1, 2] but that also has .b = 3 and .c = 4. Since JS arrays are also objects, this is of course valid, but unintended.
Now, since it's clear when parsing a=1&a=2&a[b]=3&a[c]=4 that a is an array, perhaps the deserialization code can say 'any object properties from here on are part of a sub-object' .. but then how do we differentiate between { a: [ 1, 2, { b: 3, c: 4 } ] } and { a: [ 1, 2, { b: 3 }, { c: 4 } ] }, or even what do we do when we have { a: [ { b: 3, c: 4 }, 1, 2 ] } which results in a[b]=3&a[c]=4&a=1&a=2 - how does the deserializer even know that a is an array and not an object when it starts parsing?
I have a feeling that the ambiguity introduced in these changes to $.param might cause more harm than good in the long run, especially since we already have JSON for deep objects, and anyone could do $.param( { a: json_string } );
Thoughts?
Changed September 14, 2009 05:18PM UTC by comment:3
This is my proposed fix for $.param:
http://benalman.com/code/projects/jquery-1.3.3/param.js
Note that I chose to not throw errors, because it was *significantly* less code. I'm more than happy to add that in, but I'm not sure that it's worth it (considering 1.3.2 already does [object Object]).
So, now, if $.param_compat_mode is true, things should work just like before, encoding just scalars and arrays, without any [] in the serialized string. If $.param_compat_mode is false (default), it should work as-intended, but just stringifying array items instead of recursing into them, inside arrays. It seems to me that this approach will solve any re-serialization ambiguity issues, but I'd really like someone else to vet what i've done, just to be sure. I really think that proper testing for param is critical!
Also, I have no idea how you'd want to implement the compatibility mode flag, but i do think that it's really important to put it in there (as deprecated), which might give 1.3.3-param-incompatible library authors time to address their library's limitations.
Changed September 16, 2009 08:45AM UTC by comment:4
This is just waiting a good name for the flag. John?
Changed September 17, 2009 09:59PM UTC by comment:5
Here's a legitimate diff with unit tests and everything:
Changed December 05, 2009 01:52AM UTC by comment:6
resolution: | → fixed |
---|---|
status: | reopened → closed |
This was already landed:
http://github.com/jquery/jquery/commit/67089eedf6f84acd9c16ea2a6dadadf7b13a7c84
Closed by r6534