我如何将条目从HTML5 FormData对象转换为JSON?

解决方案不应该使用jQuery。而且,它不应该简单地序列化整个FormData对象,而应该只序列化它的键/值条目。


当前回答

这解决了我的问题,这是一个对象

const formDataObject = (formData) => {

    for (const key in formData) {
        if (formData[key].startsWith('{') || formData[key].startsWith('[')) {
            try {
                formData[key] = JSON.parse(formData[key]);
                console.log("key is :", key, "form data is :", formData[key]);

            } catch (error) {
                console.log("error :", key);
            }
        }
    }

    console.log("object", formData)
}

其他回答

如果需要支持序列化嵌套字段(类似于PHP处理表单字段的方式),可以使用以下函数

function update(data, keys, value) { if (keys.length === 0) { // Leaf node return value; } let key = keys.shift(); if (!key) { data = data || []; if (Array.isArray(data)) { key = data.length; } } // Try converting key to a numeric value let index = +key; if (!isNaN(index)) { // We have a numeric index, make data a numeric array // This will not work if this is a associative array // with numeric keys data = data || []; key = index; } // If none of the above matched, we have an associative array data = data || {}; let val = update(data[key], keys, value); data[key] = val; return data; } function serializeForm(form) { return Array.from((new FormData(form)).entries()) .reduce((data, [field, value]) => { let [_, prefix, keys] = field.match(/^([^\[]+)((?:\[[^\]]*\])*)/); if (keys) { keys = Array.from(keys.matchAll(/\[([^\]]*)\]/g), m => m[1]); value = update(data[prefix], keys, value); } data[prefix] = value; return data; }, {}); } document.getElementById('output').textContent = JSON.stringify(serializeForm(document.getElementById('form')), null, 2); <form id="form"> <input name="field1" value="Field 1"> <input name="field2[]" value="Field 21"> <input name="field2[]" value="Field 22"> <input name="field3[a]" value="Field 3a"> <input name="field3[b]" value="Field 3b"> <input name="field3[c]" value="Field 3c"> <input name="field4[x][a]" value="Field xa"> <input name="field4[x][b]" value="Field xb"> <input name="field4[x][c]" value="Field xc"> <input name="field4[y][a]" value="Field ya"> <input name="field5[z][0]" value="Field z0"> <input name="field5[z][]" value="Field z1"> <input name="field6.z" value="Field 6Z0"> <input name="field6.z" value="Field 6Z1"> </form> <h2>Output</h2> <pre id="output"> </pre>

你可以试试这个

formDataToJSON($('#form_example'));

# Create a function to convert the serialize and convert the form data
# to JSON
# @param : $('#form_example');
# @return a JSON Stringify
function formDataToJSON(form) {
    let obj = {};
    let formData = form.serialize();
    let formArray = formData.split("&");

    for (inputData of formArray){
        let dataTmp = inputData.split('=');
        obj[dataTmp[0]] = dataTmp[1];
    }
    return JSON.stringify(obj);
}

对于我的目的,包括多选,如复选框,这是很好的:

JSON.stringify(Array.from((new FormData(document.querySelector('form'))).entries()).reduce((map = {}, [key, value]) => {
    return {
        ...map,
        [key]: map[key] ? [...map[key], value] : value,
    };
}, {}));

下面是一个将formData对象转换为json字符串的函数。

适用于多个条目和嵌套数组。 适用于编号和命名的输入名称数组。

例如,你可以有以下表单字段:

<select name="select[]" multiple></select>
<input name="check[a][0][]" type="checkbox" value="test"/>

用法:

let json = form2json(formData);

功能:

function form2json(data) {
        
        let method = function (object,pair) {
            
            let keys = pair[0].replace(/\]/g,'').split('[');
            let key = keys[0];
            let value = pair[1];
            
            if (keys.length > 1) {
                
                let i,x,segment;
                let last = value;
                let type = isNaN(keys[1]) ? {} : [];
                
                value = segment = object[key] || type;
                
                for (i = 1; i < keys.length; i++) {
                    
                    x = keys[i];
                    
                    if (i == keys.length-1) {
                        if (Array.isArray(segment)) {
                            segment.push(last);
                        } else {
                            segment[x] = last;
                        }
                    } else if (segment[x] == undefined) {
                        segment[x] = isNaN(keys[i+1]) ? {} : [];
                    }
                    
                    segment = segment[x];
                    
                }
                
            }
            
            object[key] = value;
            
            return object;
            
        }
        
        let object = Array.from(data).reduce(method,{});
        
        return JSON.stringify(object);
        
    }

如果你有多个相同名称的条目,例如如果你使用<SELECT multiple>或有多个<INPUT type="checkbox">具有相同的名称,你需要注意这一点,并将值创建一个数组。否则只能得到最后选中的值。

以下是es6的现代版本:

function formToJSON( elem ) {
  let output = {};
  new FormData( elem ).forEach(
    ( value, key ) => {
      // Check if property already exist
      if ( Object.prototype.hasOwnProperty.call( output, key ) ) {
        let current = output[ key ];
        if ( !Array.isArray( current ) ) {
          // If it's not an array, convert it to an array.
          current = output[ key ] = [ current ];
        }
        current.push( value ); // Add the new value to the array.
      } else {
        output[ key ] = value;
      }
    }
  );
  return JSON.stringify( output );
}

稍旧的代码(但IE11仍然不支持,因为它不支持ForEach或FormData上的条目)

function formToJSON( elem ) {
  var current, entries, item, key, output, value;
  output = {};
  entries = new FormData( elem ).entries();
  // Iterate over values, and assign to item.
  while ( item = entries.next().value )
    {
      // assign to variables to make the code more readable.
      key = item[0];
      value = item[1];
      // Check if key already exist
      if (Object.prototype.hasOwnProperty.call( output, key)) {
        current = output[ key ];
        if ( !Array.isArray( current ) ) {
          // If it's not an array, convert it to an array.
          current = output[ key ] = [ current ];
        }
        current.push( value ); // Add the new value to the array.
      } else {
        output[ key ] = value;
      }
    }
    return JSON.stringify( output );
  }