在AJAX上发送嵌套的FormData

kun*_*nde 13 string ajax nested form-data

我需要使用ajax和FormData发送一些数据,因为我想发送一个文件和一些其他参数.我通常发送数据的方式是这样的:

$.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",
        },
    },
    ...
});
Run Code Online (Sandbox Code Playgroud)

如果我不使用FormData(),我没有问题,但是当使用FormData()时,只有Lvl1上的数据是可以的,但是嵌套的任何东西都显示为像这样的字符串

<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>
Run Code Online (Sandbox Code Playgroud)

如果我使用FormData()来编码Lvl1-3中的数据,而不是[object Object]我得到[object FormData]

如何在Lvl1-3上获取数组而不是字符串?

注意:如果文件位于顶层(Lvl_1),我可以使用FormData()发送文件没有问题.我没有编写附加文件的代码,因为这不是问题,嵌套数据是.我刚刚提到了该文件,因为这就是我使用FormData()的原因.

Que*_*tin 18

URL编码表单数据没有任何本机方式来表达复杂的数据结构.它只支持简单的键=值对.

?foo=1&bar=2
Run Code Online (Sandbox Code Playgroud)

大多数表单数据解析库允许使用具有相同名称的键的数据数组

?foo=1&foo=2
Run Code Online (Sandbox Code Playgroud)

PHP在该格式之上加入了自己的语法:

?foo[]=1&foo[]=2
Run Code Online (Sandbox Code Playgroud)

允许在关联数组中使用命名键:

?foo[bar]=1&foo[baz]=2
Run Code Online (Sandbox Code Playgroud)

和嵌套数组:

?foo[bar][level2a]=1&foo[bar][level2b]=2
Run Code Online (Sandbox Code Playgroud)

由于PHP的流行,jQuery采用了这种语法,用于在传递JavaScript对象时生成表单数据data.

如果你想使用FormData那么jQuery将不会为你重新处理它.

你看到的效果是因为你试图把一个对象(我猜一个FormData实例,但你没有展示你的代码的一部分)作为第二个参数append- 在一个字符串是预期的.

您需要自己使用PHP的语法生成密钥名称.

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");
Run Code Online (Sandbox Code Playgroud)


Fre*_*ddo 7

在我的结尾,我将我的嵌套参数字符串化,并在另一端解组它们.

例如,如果我想通过:

{"sthing":
  {"sthing":"sthing"},
  {"picture":
    {"legend":"great legend"},
    {"file":"great_picture.jpg"}
  }
}
Run Code Online (Sandbox Code Playgroud)

然后我做:

// 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"];
Run Code Online (Sandbox Code Playgroud)