Opened 14 years ago
Closed 13 years ago
#4201 closed feature (fixed)
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.
Change History (6)
comment:1 Changed 14 years ago by
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:2 Changed 14 years ago by
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?
comment:3 Changed 14 years ago by
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.
comment:6 Changed 13 years ago by
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
This was already landed: http://github.com/jquery/jquery/commit/67089eedf6f84acd9c16ea2a6dadadf7b13a7c84
Closed by r6534