Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending nested FormData on AJAX

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'>=&gt;</font> <small>string</small> 
        <font color='#cc0000'>'Something'</font> 
        <i>(length=23)</i>
    'Lvl1-2' <font color='#888a85'>=&gt;</font> <small>string</small> 
        <font color='#cc0000'>''Something''</font> <i>(length=3)</i>
    'Lvl1-3' <font color='#888a85'>=&gt;</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().

like image 912
kunde Avatar asked Feb 27 '15 21:02

kunde


1 Answers

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");
like image 191
Quentin Avatar answered Oct 13 '22 01:10

Quentin