Преобразование объекта JS в данные

Как я могу преобразовать свой объект JS в FormData?

Причина, по которой я хочу это сделать, заключается в том, что у меня есть объект, который я построил из ~ 100 значений поля формы.

var item = {
   description: 'Some Item',
   price : '0.00',
   srate : '0.00',
   color : 'red',
   ...
   ...
}

Теперь меня просят добавить функцию загрузки файла в мою форму, что, конечно, невозможно через JSON, поэтому я планирую перейти на FormData. Итак, есть ли способ преобразовать свой объект JS в FormData?


person Kamran Ahmed    schedule 01.04.2014    source источник
comment
можешь поделиться своей работой / прогрессом?   -  person Ritikesh    schedule 01.04.2014
comment
как насчет JSON.stringify ()?   -  person Sunny Sharma    schedule 01.04.2014
comment
@Sunny - это создаст текст JSON в строке. Это не объект FormData.   -  person Quentin    schedule 01.04.2014
comment
Да, вы можете, вы можете добавлять к объектам formData.   -  person adeneo    schedule 01.04.2014
comment
вы можете показать нам, что вы подразумеваете под FormData? какой-то конкретный формат?   -  person Sunny Sharma    schedule 01.04.2014
comment
developer.mozilla.org/en-US/docs/Web/Guide/   -  person adeneo    schedule 01.04.2014
comment
проверьте github.com/foo123/serialiser.js, чтобы сериализовать сложные / вложенные поля формы в formData, объект, json, данные в кодировке url (автор)   -  person Nikos M.    schedule 29.01.2016
comment
В итоге мне стало проще публиковать JSON, как показано здесь: stackoverflow.com/a/6323528/470749   -  person Ryan    schedule 03.12.2019


Ответы (20)


Если у вас есть объект, вы можете легко создать объект FormData и добавить имена и значения из этого объекта в formData.

Вы не разместили код, так что это общий пример;

var form_data = new FormData();

for ( var key in item ) {
    form_data.append(key, item[key]);
}

$.ajax({
    url         : 'http://example.com/upload.php',
    data        : form_data,
    processData : false,
    contentType : false,
    type: 'POST'
}).done(function(data){
    // do stuff
});

В документации по MDN есть другие примеры.

person adeneo    schedule 01.04.2014
comment
Безопаснее использовать Object.keys () вместо цикла for-in, так как вы можете получить неожиданные результаты, поскольку for-in также выполняет итерацию для унаследованных свойств. - person Lior; 21.05.2014
comment
@Lior - item - это обычный объект, созданный OP, поэтому он не должен иметь никаких свойств, которые ему не принадлежат, если только кто-то не допустил ошибку, создав прототип чего-либо в конструкторе объекта, и в этом случае вы окажетесь в мире проблемы, и это не то, от чего мы должны защищаться. - person adeneo; 22.05.2014
comment
На самом деле, это считается лучшей практикой, особенно если вы даете решение кому-то, кому не известен контекст и среда, которую он использует, простое предупреждение сделало бы свою работу. Помните, что решения, которые вы даете на SO, предназначены не только для OP, но и для потенциально тысяч других глаз, ищущих решение, которое не нарушит их код. - person Lior; 22.05.2014
comment
@Lior - это просто добавление пар ключ / значение в FormData, добавление прототипа свойства ничего не сломает, а использование Object.keys не является ответом, так как вам не нужно получать ключи в виде массива, а затем перебирать ключи, чтобы Чтобы получить значения, вы должны использовать цикл for..in. - person adeneo; 22.05.2014
comment
Конечно, будет, вы не знаете, чего ожидает сервер ... поскольку ... in в JS является проблематичным, решение не обязательно должно быть Object.keys (), это может быть hasOwnProperty (), но это должно быть как минимум предупреждение. - person Lior; 22.05.2014
comment
@Lior - Если ваш сервер выходит из строя, когда он получает еще одну пару ключ / значение в запросе POST, вы делаете это неправильно. Я думаю, что ответ в порядке, и я не собираюсь менять его, чтобы использовать Object.keys или hasOwnProperty(), поскольку объект размещен в вопросе и не должен нуждаться ни в одном из них. Причина, по которой вы иногда видите hasOwnProperty использование в плагинах и т. Д., Заключается в том, что вы никогда не знаете, что некоторые люди могут сделать с Object конструктором, но по большей части людям не нужно проверять унаследованные свойства созданных ими объектов, это знак того, что вы, вероятно, делаете что-то не так. - person adeneo; 22.05.2014
comment
Я не согласен с тем, что некоторые сторонние библиотеки изменяют собственные прототипы, и если вы дадите ответ, вы должны предупредить о потенциальных ловушках. Но ничего, это никуда не денется ... p.s. stackoverflow.com/questions/684672/ - person Lior; 22.05.2014
comment
@BenjaminGruenbaum Вы оба упустили мою точку зрения, и по какой-то причине вместо этого вы просто были очень эмоциональны по поводу всего этого (по крайней мере, adeneo сохранил это круто и профессионально). Не было попыток кого-то обучать (хотя я думаю, что идея, что вы не можете научиться у кого-то, даже если у вас более чем в 100 раз репутация и в 100 раз больше ответов, абсурдна ... особенно когда SO - это все о обучении) . - person Lior; 26.05.2014
comment
Каким образом можно преобразовать сложный объект json (содержащий вложенные объекты и массивы) в объект FormData? - person yglodt; 30.11.2015
comment
как лучше всего преобразовать FromData в объект json для отправки на сервер? - person SuperUberDuper; 04.06.2016
comment
Если вам нужен JSON, вы должны создать JSON, а не объект formData. - person adeneo; 04.06.2016
comment
Я думаю, что это не сработает, если item[key] является объектом или массивом. Пожалуйста, взгляни на мой ответ - person Aleksandrus; 12.09.2016
comment
Конечно, это не будет работать с вложенными объектами, нужно будет выполнять итерацию по-разному в зависимости от имеющейся структуры данных. - person adeneo; 12.09.2016
comment
@adeneo. Вот более современный подход, который также позволяет избежать цикла и добавления свойств прототипа: JSFiddle. - person Robert Molina; 25.04.2019
comment
@adeneo, не могли бы вы обновить это, чтобы использовать fetch() вместо jquery, пожалуйста? - person Boris; 27.12.2019

С ES6 и более функциональным подходом к программированию ответ @ adeneo может выглядеть так:

function getFormData(object) {
    const formData = new FormData();
    Object.keys(object).forEach(key => formData.append(key, object[key]));
    return formData;
}

Или, в качестве альтернативы, используя .reduce() и стрелочные функции:

const getFormData = object => Object.keys(object).reduce((formData, key) => {
    formData.append(key, object[key]);
    return formData;
}, new FormData());
person Jacob Lauritzen    schedule 11.11.2016
comment
Я только что провел сравнение производительности ваших двух ответов, и ответ .reduce() на 1-2% быстрее. jsbench.me/m3kg87fxvt/1 - person agm1984; 13.10.2020

Эта функция добавляет все данные из объекта в FormData

Версия ES6 от @ developer033:

function buildFormData(formData, data, parentKey) {
  if (data && typeof data === 'object' && !(data instanceof Date) && !(data instanceof File)) {
    Object.keys(data).forEach(key => {
      buildFormData(formData, data[key], parentKey ? `${parentKey}[${key}]` : key);
    });
  } else {
    const value = data == null ? '' : data;

    formData.append(parentKey, value);
  }
}

function jsonToFormData(data) {
  const formData = new FormData();
  
  buildFormData(formData, data);
  
  return formData;
}

const my_data = {
  num: 1,
  falseBool: false,
  trueBool: true,
  empty: '',
  und: undefined,
  nullable: null,
  date: new Date(),
  name: 'str',
  another_object: {
    name: 'my_name',
    value: 'whatever'
  },
  array: [
    {
      key1: {
        name: 'key1'
      }
    }
  ]
};

jsonToFormData(my_data)

версия jQuery:

function appendFormdata(FormData, data, name){
    name = name || '';
    if (typeof data === 'object'){
        $.each(data, function(index, value){
            if (name == ''){
                appendFormdata(FormData, value, index);
            } else {
                appendFormdata(FormData, value, name + '['+index+']');
            }
        })
    } else {
        FormData.append(name, data);
    }
}


var formData = new FormData(),
    your_object = {
        name: 'test object',
        another_object: {
            name: 'and other objects',
            value: 'whatever'
        }
    };
appendFormdata(formData, your_object); 
person Vladimir Novopashin    schedule 27.02.2017
comment
Приятно так держать - person Vivek Doshi; 08.09.2017
comment
Работает очень хорошо! Спасибо! Мне также пришлось добавить && !(data instanceof Blob) в моем случае, чтобы загрузить свои изображения - person Clément Baconnier; 18.12.2019
comment
У меня работает хорошо, я добавил if (typeof data === 'object' && data! == null) {потому что он генерировал исключение, если значение равно null - person al000y; 14.05.2020
comment
Для версии ES6 я добавил && !(Array.isArray(data) && !data.length) в условие if, иначе пустой массив будет удален. - person Mtxz; 26.05.2020
comment
Это гениально. Решил мою проблему очень красиво. - person dearsina; 14.08.2020
comment
Потрясающие. Пришлось поменять appendFormdata(FormData, value, name + '['+index+']'); на appendFormdata(FormData, value, name + '.'+index); для меня! - person Ayo K; 14.09.2020
comment
Ответ не может обрабатывать массив. - person Ben Carp; 25.10.2020

Попробуйте функцию JSON.stringify, как показано ниже

var postData = JSON.stringify(item);
var formData = new FormData();
formData.append("postData",postData );
person Udayraj Khuman    schedule 19.12.2018
comment
Это лучший способ добиться этого. - person Rob; 10.06.2019
comment
его продолжают добавлять json после нескольких раз отладки ошибок - person Snow Bases; 16.07.2019
comment
Супер, простое и удобное решение. Сэкономил мои часы. - person Pushprajsinh Chudasama; 31.10.2020
comment
Это должен быть принятый ответ. - person Armaan; 03.12.2020
comment
Это не сработает, так как при отправке данных формы он преобразуется в строку, что означает два раза строковую - person Richen Yadav; 19.05.2021

Остальные ответы были для меня неполными. Я начал с ответа @Vladimir Novopashin и изменил его. Вот что мне было нужно и что я обнаружил:

  • Поддержка файла
  • Поддержка массива
  • Ошибка: файл внутри сложного объекта нужно добавлять с .prop вместо [prop]. Например, formData.append('photos[0][file]', file) не работал в Google Chrome, а formData.append('photos[0].file', file) работал
  • Игнорировать некоторые свойства в моем объекте

Следующий код должен работать в IE11 и вечнозеленых браузерах.

function objectToFormData(obj, rootName, ignoreList) {
    var formData = new FormData();

    function appendFormData(data, root) {
        if (!ignore(root)) {
            root = root || '';
            if (data instanceof File) {
                formData.append(root, data);
            } else if (Array.isArray(data)) {
                for (var i = 0; i < data.length; i++) {
                    appendFormData(data[i], root + '[' + i + ']');
                }
            } else if (typeof data === 'object' && data) {
                for (var key in data) {
                    if (data.hasOwnProperty(key)) {
                        if (root === '') {
                            appendFormData(data[key], key);
                        } else {
                            appendFormData(data[key], root + '.' + key);
                        }
                    }
                }
            } else {
                if (data !== null && typeof data !== 'undefined') {
                    formData.append(root, data);
                }
            }
        }
    }

    function ignore(root){
        return Array.isArray(ignoreList)
            && ignoreList.some(function(x) { return x === root; });
    }

    appendFormData(obj, rootName);

    return formData;
}
person Gudradain    schedule 20.03.2018
comment
Единственный ответ, поддерживающий массивы, объекты и файлы. - person sotn; 04.07.2018
comment
Привет, а зачем вы добавляете Файл в корень? Можно ли добавить его и к ребенку? - person Cedric Arnould; 26.09.2018
comment
@CedricArnould Это может быть недоразумение, но метод рекурсивен, поэтому даже если он написан formData.append(root, data), это не означает, что он добавлен в корень. - person Gudradain; 26.09.2018
comment
Я понимаю ваш ответ, как ни странно, когда я получаю результат на сервере, у меня есть уникальная Коллекция файлов и данных. Но я вижу, что в файле имя дает информацию, к которому он подключен. Возможно, проблема связана с .Net Core и тем, как он управляет загружаемыми файлами. Спасибо за Ваш ответ. - person Cedric Arnould; 27.09.2018
comment
Я пытаюсь использовать это, но нет примера использования. ожидаемый формат параметра ignoreList был бы очень полезен. - person jpro; 09.06.2020

У меня был сценарий, в котором вложенный JSON нужно было сериализовать линейным образом, пока создаются данные формы, поскольку именно так сервер ожидает значения. Итак, я написал небольшую рекурсивную функцию, которая переводит JSON, который выглядит так:

{
   "orderPrice":"11",
   "cardNumber":"************1234",
   "id":"8796191359018",
   "accountHolderName":"Raj Pawan",
   "expiryMonth":"02",
   "expiryYear":"2019",
   "issueNumber":null,
   "billingAddress":{
      "city":"Wonderland",
      "code":"8796682911767",
      "firstname":"Raj Pawan",
      "lastname":"Gumdal",
      "line1":"Addr Line 1",
      "line2":null,
      "state":"US-AS",
      "region":{
         "isocode":"US-AS"
      },
      "zip":"76767-6776"
   }
}

Примерно так:

{
   "orderPrice":"11",
   "cardNumber":"************1234",
   "id":"8796191359018",
   "accountHolderName":"Raj Pawan",
   "expiryMonth":"02",
   "expiryYear":"2019",
   "issueNumber":null,
   "billingAddress.city":"Wonderland",
   "billingAddress.code":"8796682911767",
   "billingAddress.firstname":"Raj Pawan",
   "billingAddress.lastname":"Gumdal",
   "billingAddress.line1":"Addr Line 1",
   "billingAddress.line2":null,
   "billingAddress.state":"US-AS",
   "billingAddress.region.isocode":"US-AS",
   "billingAddress.zip":"76767-6776"
}

Сервер будет принимать данные формы, которые находятся в этом преобразованном формате.

Вот функция:

function jsonToFormData (inJSON, inTestJSON, inFormData, parentKey) {
    // http://stackoverflow.com/a/22783314/260665
    // Raj: Converts any nested JSON to formData.
    var form_data = inFormData || new FormData();
    var testJSON = inTestJSON || {};
    for ( var key in inJSON ) {
        // 1. If it is a recursion, then key has to be constructed like "parent.child" where parent JSON contains a child JSON
        // 2. Perform append data only if the value for key is not a JSON, recurse otherwise!
        var constructedKey = key;
        if (parentKey) {
            constructedKey = parentKey + "." + key;
        }

        var value = inJSON[key];
        if (value && value.constructor === {}.constructor) {
            // This is a JSON, we now need to recurse!
            jsonToFormData (value, testJSON, form_data, constructedKey);
        } else {
            form_data.append(constructedKey, inJSON[key]);
            testJSON[constructedKey] = inJSON[key];
        }
    }
    return form_data;
}

Призыв:

        var testJSON = {};
        var form_data = jsonToFormData (jsonForPost, testJSON);

Я использую testJSON только для просмотра преобразованных результатов, так как я не смогу извлечь содержимое form_data. Пост-вызов AJAX:

        $.ajax({
            type: "POST",
            url: somePostURL,
            data: form_data,
            processData : false,
            contentType : false,
            success: function (data) {
            },
            error: function (e) {
            }
        });
person Raj Pawan Gumdal    schedule 15.02.2017
comment
Привет, Радж, а как насчет массивов? Допустим, у вас более 1 платежных адресов. Как бы вы это исправить? - person Sam; 01.07.2018
comment
Я нашел ответ! Ваш пост действительно полезен. Спасибо! - person Sam; 01.07.2018

Вы можете просто использовать:

formData.append('item', JSON.stringify(item));
person Ahsan Farooq    schedule 03.12.2020

Извините за поздний ответ, но я боролся с этим, поскольку Angular 2 в настоящее время не поддерживает загрузку файлов. Итак, способ сделать это - отправить XMLHttpRequest с FormData. Итак, я создал функцию для этого. Я использую Машинопись. Чтобы преобразовать его в Javascript, просто удалите объявление типов данных.

/**
     * Transforms the json data into form data.
     *
     * Example:
     *
     * Input:
     * 
     * fd = new FormData();
     * dob = {
     *  name: 'phone',
     *  photos: ['myphoto.jpg', 'myotherphoto.png'],
     *  price: '615.99',
     *  color: {
     *      front: 'red',
     *      back: 'blue'
     *  },
     *  buttons: ['power', 'volup', 'voldown'],
     *  cameras: [{
     *      name: 'front',
     *      res: '5Mpx'
     *  },{
     *      name: 'back',
     *      res: '10Mpx'
     *  }]
     * };
     * Say we want to replace 'myotherphoto.png'. We'll have this 'fob'.
     * fob = {
     *  photos: [null, <File object>]
     * };
     * Say we want to wrap the object (Rails way):
     * p = 'product';
     *
     * Output:
     *
     * 'fd' object updated. Now it will have these key-values "<key>, <value>":
     *
     * product[name], phone
     * product[photos][], myphoto.jpg
     * product[photos][], <File object>
     * product[color][front], red
     * product[color][back], blue
     * product[buttons][], power
     * product[buttons][], volup
     * product[buttons][], voldown
     * product[cameras][][name], front
     * product[cameras][][res], 5Mpx
     * product[cameras][][name], back
     * product[cameras][][res], 10Mpx
     * 
     * @param {FormData}  fd  FormData object where items will be appended to.
     * @param {Object}    dob Data object where items will be read from.
     * @param {Object =   null} fob File object where items will override dob's.
     * @param {string =   ''} p Prefix. Useful for wrapping objects and necessary for internal use (as this is a recursive method).
     */
    append(fd: FormData, dob: Object, fob: Object = null, p: string = ''){
        let apnd = this.append;

        function isObj(dob, fob, p){
            if(typeof dob == "object"){
                if(!!dob && dob.constructor === Array){
                    p += '[]';
                    for(let i = 0; i < dob.length; i++){
                        let aux_fob = !!fob ? fob[i] : fob;
                        isObj(dob[i], aux_fob, p);
                    }
                } else {
                    apnd(fd, dob, fob, p);
                }
            } else {
                let value = !!fob ? fob : dob;
                fd.append(p, value);
            }
        }

        for(let prop in dob){
            let aux_p = p == '' ? prop : `${p}[${prop}]`;
            let aux_fob = !!fob ? fob[prop] : fob;
            isObj(dob[prop], aux_fob, aux_p);
        }
    }
person Aleksandrus    schedule 12.09.2016
comment
Вы должны включить индексы массива вместо [], чтобы свойства объекта внутри числового массива оставались неизменными. - person Vicary; 26.10.2016

Рекурсивно

const toFormData = (f => f(f))(h => f => f(x => h(h)(f)(x)))(f => fd => pk => d => {
  if (d instanceof Object) {
    Object.keys(d).forEach(k => {
      const v = d[k]
      if (pk) k = `${pk}[${k}]`
      if (v instanceof Object && !(v instanceof Date) && !(v instanceof File)) {
        return f(fd)(k)(v)
      } else {
        fd.append(k, v)
      }
    })
  }
  return fd
})(new FormData())()

let data = {
  name: 'John',
  age: 30,
  colors: ['red', 'green', 'blue'],
  children: [
    { name: 'Max', age: 3 },
    { name: 'Madonna', age: 10 }
  ]
}
console.log('data', data)
document.getElementById("data").insertAdjacentHTML('beforeend', JSON.stringify(data))

let formData = toFormData(data)

for (let key of formData.keys()) {
  console.log(key, formData.getAll(key).join(','))
  document.getElementById("item").insertAdjacentHTML('beforeend', `<li>${key} = ${formData.getAll(key).join(',')}</li>`)
}
<p id="data"></p>
<ul id="item"></ul>

person vmartins    schedule 18.02.2020
comment
лучший ответ имхо - person ling; 20.04.2020

Вот короткое и приятное решение с использованием 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

person Nelson King    schedule 21.08.2020

В моем случае у моего объекта также было свойство, которое было массивом файлов. Поскольку они бинарные, с ними следует обращаться по-другому - индекс не обязательно должен быть частью ключа. Итак, я изменил ответ @Vladimir Novopashin и @ developer033:

export function convertToFormData(data, formData, parentKey) {
  if(data === null || data === undefined) return null;

  formData = formData || new FormData();

  if (typeof data === 'object' && !(data instanceof Date) && !(data instanceof File)) {
    Object.keys(data).forEach(key => 
      convertToFormData(data[key], formData, (!parentKey ? key : (data[key] instanceof File ? parentKey : `${parentKey}[${key}]`)))
    );
  } else {
    formData.append(parentKey, data);
  }

  return formData;
}
person Elnoor    schedule 04.08.2019

Возможно, вы ищете этот код, который получает ваш объект javascript, создает FormData, а затем отправьте его на свой сервер, используя новый Получить API:

    let myJsObj = {'someIndex': 'a value'};

    let datos = new FormData();
    for (let i in myJsObj){
        datos.append( i, myJsObj[i] );
    }

    fetch('your.php', {
        method: 'POST',
        body: datos
    }).then(response => response.json())
        .then(objson => {
            console.log('Success:', objson);
        })
        .catch((error) => {
            console.error('Error:', error);
        });
person Oswaldo Rodriguez Gonzalez    schedule 30.04.2020

Вложенные объекты и файлы

Следующие решения обрабатывают вложенные объекты, массивы и файлы.

const buildFormData = (formData: FormData, data: FormVal, parentKey?: string) => {
    if (Array.isArray(data)) {
        data.forEach((el) => {
            buildFormData(formData, el, parentKey)
        })

    } else if (typeof data === "object" && !(data instanceof File)) {
        Object.keys(data).forEach((key) => {
            buildFormData(formData, (data as FormDataNest)[key], parentKey ? `${parentKey}.${key}` : key)
        })

    } else {
        if (isNil(data)) {
            return
        }

        let value = typeof data === "boolean" || typeof data === "number" ? data.toString() : data
        formData.append(parentKey as string, value)
    }
}

export const getFormData = (data: Record<string, FormDataNest>) => {
    const formData = new FormData()

    buildFormData(formData, data)

    return formData
}

Типы

type FormDataPrimitive = string | Blob | number | boolean

interface FormDataNest {
  [x: string]: FormVal
}

type FormVal = FormDataNest | FormDataPrimitive
person Ben Carp    schedule 25.10.2020
comment
Мне нравится решение, но я бы рекомендовал начать с if (isNil(data)) return, потому что typeof null === 'object'. - person Julian; 25.10.2020

Этот метод преобразует объект JS в FormData:

function convertToFormData(params) {
    return Object.entries(params)
        .reduce((acc, [key, value]) => {
            if (Array.isArray(value)) {
                value.forEach((v, k) => acc.append(`${key}[${k}]`, value));
            } else if (typeof value === 'object' && !(value instanceof File) && !(value instanceof Date)) {
                Object.entries(value).forEach((v, k) => acc.append(`${key}[${k}]`, value));
            } else {
                acc.append(key, value);
            }

            return acc;
        }, new FormData());
}

person Monkey Monk    schedule 18.07.2019
comment
Просто исправьте итерацию вызова записей вложенных объектов: Object.entries(value).forEach((v, k) => acc.append(`${key}[${v[0]}]`, v[1])); - person heber gentilin; 28.07.2020

Вы можете просто установить qs:

npm i qs

Просто импортируйте:

import qs from 'qs'

Передать объект qs.stringify():

var item = {
   description: 'Some Item',
   price : '0.00',
   srate : '0.00',
   color : 'red',
   ...
   ...
}

qs.stringify(item)
person Balaj Khan    schedule 16.09.2019

Я использовал это для публикации моих данных объекта как данных формы.

const encodeData = require('querystring');

const object = {type: 'Authorization', username: 'test', password: '123456'};

console.log(object);
console.log(encodeData.stringify(object));
person Yunus ER    schedule 09.03.2020

Я ссылаюсь на это из ответа Гудрадайна. Немного редактирую в формате Typescript.

class UtilityService {
    private appendFormData(formData, data, rootName) {

        let root = rootName || '';
        if (data instanceof File) {
            formData.append(root, data);
        } else if (Array.isArray(data)) {
            for (var i = 0; i < data.length; i++) {
                this.appendFormData(formData, data[i], root + '[' + i + ']');
            }
        } else if (typeof data === 'object' && data) {
            for (var key in data) {
                if (data.hasOwnProperty(key)) {
                    if (root === '') {
                        this.appendFormData(formData, data[key], key);
                    } else {
                        this.appendFormData(formData, data[key], root + '.' + key);
                    }
                }
            }
        } else {
            if (data !== null && typeof data !== 'undefined') {
                formData.append(root, data);
            }
        }
    }

    getFormDataFromObj(data) {
        var formData = new FormData();

        this.appendFormData(formData, data, '');

        return formData;
    }
}

export let UtilityMan = new UtilityService();
person Mikhael Pramodana    schedule 27.05.2020

Возможно, я немного опоздал на вечеринку, но это то, что я создал для преобразования единственного объекта в FormData.

function formData(formData, filesIgnore = []) {
  let data = new FormData();

  let files = filesIgnore;

  Object.entries(formData).forEach(([key, value]) => {
    if (typeof value === 'object' && !files.includes(key)) {
      data.append(key, JSON.stringify(value) || null);
    } else if (files.includes(key)) {
      data.append(key, value[0] || null);
    } else {
      data.append(key, value || null);
    }
  })

  return data;
}

Как это работает? Он преобразует и вернет все свойства, кроме объектов File, которые вы установили в списке игнорирования (2-й аргумент. Если бы кто-нибудь мог сказать мне лучший способ определить это, это поможет!) В строку json с использованием JSON.stringify. Затем на вашем сервере вам просто нужно преобразовать его обратно в объект JSON.

Пример:

let form = {
  first_name: 'John',
  last_name: 'Doe',
  details: {
    phone_number: 1234 5678 910,
    address: '123 Some Street',
  },
  profile_picture: [object FileList] // set by your form file input. Currently only support 1 file per property.
}

function submit() {
  let data = formData(form, ['profile_picture']);

  axios.post('/url', data).then(res => {
    console.log('object uploaded');
  })
}

Я все еще новичок в HTTP-запросах и JavaScript, поэтому буду очень признателен за любые отзывы!

person Gibbu    schedule 13.06.2020

Просто это можно сделать:

var item: { some1: "ajbd" , some2: "dds".. }
let myFormData = new FormData();
      
       const abc = item.some1;
       const xyz = item.some2;

          myFormData.append('field1', abc);
          myFormData.append('field2', xyz);
    
    fetch('http:url', {
      method: 'POST',
      headers: {
        'Content-Type': false,
      },
      body: myFormData,
    }).
do promise ..
person NoobCoder    schedule 08.07.2021

Попробуйте obj2fd => https://www.npmjs.com/package/obj2fd.

import obj2fd from 'obj2fd'

let data = {a:1, b:2, c:{ca:1}};
let dataWithFormData = obj2fd(data);
//result => [a=>1, b=>2, c=>[ca=>1]]
person Manioz    schedule 24.06.2018