问题
I need to send some data using ajax and FormData, because I want to send a file and some other parameters. The way I usually send data is this:
$.ajax({
type: 'POST',
url: 'some_url',
dataType: 'json',
processData:false,
contentType:false,
data:{
Lvl_1-1: 'something',
Lvl_1-2: 'something',
Lvl_1-3: {
Lvl_1-3-1: "something",
Lvl_1-3-2: "something",
Lvl_1-3-3: "something",
},
},
...
});
If I don't use FormData(), I have no problem, but when using FormData(), only the data on Lvl1 is ok, but anything nested is displayed as string like this
<b>array</b> <i>(size=3)</i>
'Lvl1-1' <font color='#888a85'>=></font> <small>string</small>
<font color='#cc0000'>'Something'</font>
<i>(length=23)</i>
'Lvl1-2' <font color='#888a85'>=></font> <small>string</small>
<font color='#cc0000'>''Something''</font> <i>(length=3)</i>
'Lvl1-3' <font color='#888a85'>=></font> <small>string</small>
<font color='#cc0000'>'[object Object]'</font> <i>(length=17)</i>
If I use FormData() to encode the data inside Lvl1-3, instead of [object Object]
I get [object FormData]
How do I get an array instead of string on Lvl1-3?
NOTE: If the file is on top level (Lvl_1) I can send the file with no problems using FormData(). I didn't wrote the code of the file attached because that's not the problem, nested data is. I just mentioned the file because that's why I'm using FormData().
回答1:
URL Encoded form data doesn't have any native way to express complex data structures. It only supports simple key=value pairs.
?foo=1&bar=2
Most form data parsing libraries allow arrays of data using keys with the same name
?foo=1&foo=2
PHP bolted its own syntax on top of that format:
?foo[]=1&foo[]=2
which allowed for named keys in an associative array:
?foo[bar]=1&foo[baz]=2
and nested arrays:
?foo[bar][level2a]=1&foo[bar][level2b]=2
Due to the prevalence of PHP, jQuery adopted that syntax for generating form data when you pass a JavaScript object to data
.
If you want to use FormData
then jQuery won't reprocess it for you.
The effect you are seeing is because you are trying to put an object (I'm guessing a FormData instance, but you haven't showed that part of your code) as the second argument to append
- where a string is expected.
You need to generate the key names using PHP's syntax yourself.
form_data_instance.append("Lvl_1-3[Lvl_1-3-1]", "something");
form_data_instance.append("Lvl_1-3[Lvl_1-3-2]", "something");
form_data_instance.append("Lvl_1-3[Lvl_1-3-3]", "something");
回答2:
On my end, I stringify my nested parameters and parse them on the other end.
For instance, if I want to pass:
{"sthing":
{"sthing":"sthing"},
{"picture":
{"legend":"great legend"},
{"file":"great_picture.jpg"}
}
}
Then I do:
// On the client side
const nestedParams = {"sthing":
{"sthing":"sthing"},
{"picture":
{"legend":"great legend"}
}
};
const pictureFile = document.querySelector('input[type="file"]')[0];
const formDataInstance = new FormData;
formDataInstance.append("nested_params": JSON.stringify(nested_params);
formDataInstance.append("file": document.querySelector('input[type="file"]')[0]);
// On the server side
params["nested_params"] = JSON.parse(params["nested_params"]);
params["nested_params"]["sthing"]["picture"]["file"] = params["file"];
来源:https://stackoverflow.com/questions/28774746/sending-nested-formdata-on-ajax