我如何将条目从HTML5 FormData对象转换为JSON?
解决方案不应该使用jQuery。而且,它不应该简单地序列化整个FormData对象,而应该只序列化它的键/值条目。
我如何将条目从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 );
}