FormData добавляет вложенный объект

Можно ли добавить вложенный объект в FormData?

let formData = new FormData();
let data = {
    title: 'title',
    text: 'text',
    preview: {p_title:'p title', p_text: 'p text'}
};

$.each(data, function(key, value) {
    formData.append(key, value);
});

Консоль сервера - console.info (req.body)

{
    title: 'title',
    text: 'text',
    preview: '[object Object]'
}

Как я могу узнать точную стоимость preview: {p_title:'p title', p_text: 'p text'}?

Вам действительно нужна такая структура, как на стороне сервера? в этом случае вам придется пройти по вашему объекту и использовать нотацию key[subkey], например formData.append('preview[p_title]', 'p title');. Но в противном случае просто отправьте его как строку JSON и проанализируйте ее на стороне сервера, обычно это проще всего как для отправки, так и для получения.

Kaiido 29.09.2018 13:05

На самом деле я новичок в бэкэнд-кодировании, моя структура mongodb вложена, поэтому я выбираю эту структуру со стороны клиента для отправки данных, я думал, что это правильный путь, я думаю, что самый простой способ не пытаться передавать вложенную структуру со стороны клиента и просто повторно -структура с сервера перед отправкой в ​​db @Kaiido

ShibinRagh 01.10.2018 08:18
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
27
2
23 907
9

Ответы 9

Значения FormData автоматически преобразуются в string. Вы можете попробовать сделать это с помощью Blob.

Или просто поместите его как строку, используя JSON.stringify(obj).

$.each(data, function(key, value){
    if (typeof(value) === 'object') {
        value = new Blob([JSON.stringify(value)], {type : 'application/json'});// or just JSON.stringify(value)
    }
    formData.append(key, value);
});

Добавлен сниппет @ShibinRagh

Orest Savchak 29.09.2018 10:16

Зачем преобразовывать его в Blob? Просто отправьте JSON в виде строки, вы ничего не выиграете, отправив его как составной двоичный файл, поскольку это не двоичные данные.

Kaiido 29.09.2018 13:06

Не работает, если значением является файл.

thisismydesign 22.03.2021 14:32

Вот «Удобная функция JavaScript, преобразующая объект в экземпляр FormData» github, также доступная как пакет npm, очень простая в использовании.

let data = {
    title: 'title',
    text: 'text',
    preview: {p_title:'p title', p_text: 'p text'}
};

var formData = objectToFormData(data);

Чтобы добавить объект в formData, вам нужно сначала преобразовать его в строку, например:

let objToAppend= {
  key1: value1,
  key2: value2,
}
let formData = new FormData();
formData.append('obj', JSON.stringify(objToAppend));

Затем на стороне сервера, чтобы получить к нему доступ, вам нужно сначала проанализировать его с помощью JSON.parse(). Надеюсь, это поможет!

Это FormData, вы написали FormDate

vinu_ser 11.05.2020 05:48

@ustaad Привет, спасибо за внимание. Я его обновил.

Harshit Agarwal 11.05.2020 06:38

Не работает, если значением является файл.

thisismydesign 22.03.2021 14:31
let formData = new FormData();
let data = {
  title: 'title',
  text: 'text',
  preview: {p_title:'p title', p_text: 'p text'}
};

for(let dataKey in data) {
  if (dataKey === 'preview') {
    // append nested object
    for (let previewKey in data[dataKey]) {
      formData.append(`preview[${previewKey}]`, data[dataKey][previewKey]);
    }
  }
  else {
    formData.append(dataKey, data[dataKey]);
  }
}

Форма консолиДанные

for (let val of formData.entries()) {
  console.info(val[0]+ ', ' + val[1]); 
}

Наличие файла в качестве значения JSON.stringify для меня не сработало, это сработало.

thisismydesign 22.03.2021 14:31

Попробуйте данные от объекта к форме. Это удобная функция JavaScript, преобразующая объекты в экземпляры FormData.

import { objectToFormData } from 'object-to-formdata';

const object = {
  /**
   * key-value mapping
   * values can be primitives or objects
   */
};

const options = {
  /**
   * include array indices in FormData keys
   * defaults to false
   */
  indices: false,

  /**
   * treat null values like undefined values and ignore them
   * defaults to false
   */
  nullsAsUndefineds: false,

  /**
   * convert true or false to 1 or 0 respectively
   * defaults to false
   */
  booleansAsIntegers: false,
};

const formData = objectToFormData(
  object,
  options, // optional
  existingFormData, // optional
  keyPrefix, // optional
);

console.info(formData);

Это для меня делает работу:

используйте . для разделения ключа и subKey

let formData = new FormData();
let data = {
  title: 'title',
  text: 'text',
  preview: {p_title:'p title', p_text: 'p text'}
};

for(let key in data) {
  if (typeof(data[key]) === 'object') {
    for (let subKey in data[key]) {
      formData.append(`${key}.${subKey}`, data[key][subKey]);
    }
  }
  else {
    formData.append(key, data[key]);
  }
}

Вам не нужно использовать какие-либо сторонние модули, и JSON.stringify() не идеален, если у вас есть вложенные объекты. Вместо этого вы можете использовать Object.entries().

// If this is the object you want to convert to FormData...
const item = {
    description: 'First item',
    price: 13,
    photo: File
};

const formData = new FormData();

Object.entries(item).forEach(([key, value]) => {
    formData.append(key, value);
});

// At this point, you can then pass formData to your handler method

Узнайте больше о Object.entries() здесь - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

используйте hashName [keyName]

let formData = new FormData();
let data = {
  title: 'title',
  text: 'text',
  preview: {p_title:'p title', p_text: 'p text'}
};

for(let key in data) {
  if (typeof(data[key]) === 'object') {
    for (let subKey in data[key]) {
      formData.append('${key}[${subKey}]', data[key][subKey]);
    }
  }
  else {
    formData.append(key, data[key]);
  }
}

Прежде всего, прошу прощения за плохой английский.

Я что-то сделал для правильного получения данных на стороне сервера, а не когда писал в консоль. Я надеюсь, ты хочешь это сделать.

Мне пришлось написать функцию javascript, чтобы получать вложенные данные на стороне клиента на стороне сервера.

Для этого я написал функцию obj2FormData (). Квадратные скобки вроде работают.

function obj2FormData(obj, formData = new FormData()){

    this.formData = formData;

    this.createFormData = function(obj, subKeyStr = ''){
        for(let i in obj){
            let value          = obj[i];
            let subKeyStrTrans = subKeyStr ? subKeyStr + '[' + i + ']' : i;

            if (typeof(value) === 'string' || typeof(value) === 'number'){

                this.formData.append(subKeyStrTrans, value);

            } else if (typeof(value) === 'object'){

                this.createFormData(value, subKeyStrTrans);

            }
        }
    }

    this.createFormData(obj);

    return this.formData;
}

При отправке данных с помощью Ajax мы конвертируем вложенный объект в объект FormData.

let formData = obj2FormData({
    name : 'Emrah',
    surname : 'Tuncel',
    birth: 1983,
    child : {
        name: 'Eylul',
        surname: 'Tuncel',
        toys: ['ball', 'baby']
    },
    color: ['red', 'yellow']
});

Теперь давайте отправим данные FormData, которые мы преобразовали с помощью ajax.

const xhr = new XMLHttpRequest();
xhr.addEventListener('load', response => {
    //AJAX RESPONSE >>

    console.info(response);

    //AJAX RESPONSE //
});
xhr.open('POST','response.php');
xhr.send(formData);

Когда я нажал данные на экране с помощью PHP, я получил именно тот результат, который хотел. Не имеет значения, какой это метод - POST или GET.

response.php

<pre><? print_r($_GET) ?></pre>
<pre><? print_r($_POST) ?></pre>

Результат был следующим.

Array
(
    [name] => Emrah
    [surname] => Tuncel
    [birth] => 1983
    [child] => Array
        (
            [name] => Eylul
            [surname] => Tuncel
            [toys] => Array
                (
                    [0] => ball
                    [1] => baby
                )

        )

    [color] => Array
        (
            [0] => red
            [1] => yellow
        )

)

Надеюсь, это принесет пользу вашему бизнесу.

Другие вопросы по теме