If I try to use $.ajax
to POST a data dictionary like:
{
list: ["fake_id_0"],
mapType: "fakeToRealId"
}
jQuery does something strange to it; it transforms the data into:
{
list[]: ["fake_id_0"],
mapType: "fakeToRealId"
}
As you can see, it adds brackets to the list
key, but not the mapType
key. Now in a
general REST sense, yes it is common for people to name keys with array values with brackets ... but my server doesn't work that way, so if I try to POST list[]
I have problems.
I have tracked this problem down to $.ajax
's handling of the parseData option, in this bit of code:
// Convert data if not already a string
if ( s.data && s.processData && typeof s.data !== "string" ) {
s.data = jQuery.param( s.data, s.traditional );
}
and if I use processData: false
it does skip that block ... but then it also doesn't URLEncode my data for me.
So, my question is: how do make $.ajax
calls with processData: true
without having jQuery modify my key names on me? Or failing that, how do I use processData: false
, but still get every effect from that option except the bracket-adding?
P.S. Or, if this is all non-standard jQuery behavior, being caused by some plug-in I have, please let me know that instead :-)
* EDIT *
I answered my own question, then deleted that answer because I realized that it was flawed. I answered that setting the option traditional:true
(in the $.ajax
call) fixes the brackets, and it does ... but it also has a side effect, which is that it will not serialize nested objects.
So my revised question is: how do make $.ajax
calls with processData: true
without having jQuery modify my key names on me AND without disabling its serialization of nested properties? In other words, how do I have jQuery do everything the same as it currently does ... except not add brackets to my keys?
As you realized this is not a bug. The brackets were put there specifically to solve problems with multi-level objects, after version 1.4 I believe. You can have a look to .param() itself to understand why. http://api.jquery.com/jQuery.param/
I believe what you want is not possible and good way to verify is to try end encode one string by hand. I believe you will not be able to encode it in way that is uniquely decodable, without the brackets.
To amend my answer, quoting from the above link
Note: Because some frameworks have limited ability to parse serialized arrays, developers should exercise caution when passing an obj argument that contains objects or arrays nested within another array.
Note: Because there is no universally agreed-upon specification for param strings, it is not possible to encode complex data structures using this method in a manner that works ideally across all languages supporting such input. Use JSON format as an alternative for encoding complex data instead.
So if you server is ready to parse json, you can then send your request like this.
$.ajax({
url: 'something',
type: 'GET',
data: JSON.stringify(data),
contentType: 'application/json; charset=utf-8',
});
I know it's already implied by the question body, but here's how you avoid this wonderful feature of jQuery's. If you have:
$.get(api_url, {my_param: my_arguments})
change it to:
$.get(api_url, $.param({my_param: my_arguments}, true))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With