ajax - 在 AJAX 上发送嵌套的 FormData

标签 ajax string 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",
        },
    },
    ...
});

如果我不使用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>

如果我使用 FormData() 对 Lvl1-3 中的数据进行编码,而不是 [object Object]我得到 [object FormData]
如何在 Lvl1-3 上获取数组而不是字符串?

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

最佳答案

为了补充昆汀的答案,我有一些这样的 PHP Laravel 代码:

    $tags = [];
    foreach ($request->input('tags') as $tag) {
        if (!is_array($tag)) {
            $new_tag = Tag::generate($tag);
            array_push($tags, $new_tag->id);
        } else {
            array_push($tags, $tag['id']);
        }
    }
你可以看到我从一个空数组开始,然后用 $request->input('tags') 中的值填充它。 .该请求输入是一个多维数组,因此遇到了这个问题中描述的问题。它仅限 使用 FormData 和 multipart/form-data 时出现表单编码类型。
我可以用 Quentin 的回答加上这个客户端 JavaScript 代码来修复它:
this.example.tags.forEach((tag, i) => {
    if (Object.prototype.toString.call(tag) === '[object String]') {
        payload.append(`tags[${i}]`, tag);
    } else {
        Object.keys(tag).forEach(field => payload.append(`tags[${i}][${field}]`, tag[field]));
    }
});
此代码首先检查它要添加到 FormData 的标记是否为字符串。如果是这样,它是一个新的、不存在的标签。然后它通过它的索引号添加它。如果标签已经存在,我只发送客户端拥有的所有值。在我的情况下,服务器只关心名称和 ID(用于与该行 ID 的 SQL 关系),所以这很好,但是使用诸如 arr[index][field] 之类的语法是一个很好的练习。 .
如果您研究昆汀和我的回答,您应该能够看到这种模式。我的例子在本质上也有点不重要,所以我认为最好检查一下。
为了完全理解,下面是有效载荷的样子:
  'tags' => 
  array (
    0 => 
    array (
      'id' => '2',
      'name' => 'React JS',
    ),
    1 => 
    array (
      'id' => '5',
      'name' => 'JSON Web Tokens',
    ),
    2 => 'Sandwiches',
  ),
你可以看到有3个标签。前两个已经存在。第三个在我的数据库中不存在,因此它以字符串值而不是对象的形式出现。 Laravel/PHP 不喜欢嵌套对象“现有标签”,所以我不得不修改 FormData(它有图像,因此是多部分编码类型)。
对于上下文,这是我的整个 submitForm 函数:
const payload = new FormData();

Object.keys(this.example).forEach(field => payload.append(field, this.example[field]));

this.example.tags.forEach((tag, i) => {
    if (Object.prototype.toString.call(tag) === '[object String]') {
        payload.append(`tags[${i}]`, tag);
    } else {
        Object.keys(tag).forEach(field => payload.append(`tags[${i}][${field}]`, tag[field]));
    }
});

this.example.images.forEach(image => payload.append('images[]', image));

const response = await axios.post(route('admin.examples.create'), payload);
引用:
Check if a variable is a string in JavaScript

关于ajax - 在 AJAX 上发送嵌套的 FormData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28774746/

相关文章:

jQuery为一个类的多个实例替换字符串中的字符

C++ 嵌套宏?

elasticsearch - 嵌套聚合Elasticsearch

javascript - ajax 请求删除后页面重新加载

javascript - 如何使用 JavaScript 在 MVC 项目中加载 View ,然后加载其中的部分 View ?

javascript - 如何在回调函数中修改数组?

javascript - 页面刷新时如何运行ajax脚本

c# - String.Trim() 删除的内容超出需要?

php - 如何检测文本中的电话号码(并替换它们)?

loops - 对于循环数学测验生成器,循环不重复