Sending nested FormData on AJAX

不想你离开。 提交于 2019-12-21 07:19:08

问题


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().


回答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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!