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

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


当前回答

使用JSON.stringify()中描述的toJSON

如果值具有toJSON()方法,则它负责定义将序列化的数据。

这里有一个小技巧。

var fd = new FormData(document.forms[0]); fd.toJSON = function() { const o = {}; this.forEach((v, k) => { v = this.getAll(k); o[k] = v.length == 1 ? v[0] : (v.length >= 1 ? v : null); }); return o; }; document.write(`<pre>${JSON.stringify(fd)}</pre>`) <form action="#"> <input name="name" value="Robinson" /> <input name="items" value="Vin" /> <input name="items" value="Fromage" /> <select name="animals" multiple id="animals"> <option value="tiger" selected>Tigre</option> <option value="turtle" selected>Tortue</option> <option value="monkey">Singe</option> </select> </form>

其他回答

如果下列物品能满足你的需求,那你就很幸运了:

你想转换一个数组的数组,如[['key','value1'], ['key2','value2'](就像FormData给你的)到一个key->值对象,如{key1: 'value1', key2: 'value2'},并将其转换为JSON字符串。 你的目标浏览器/设备是最新的ES6解释器,或者是用babel之类的东西编译。 你想用最小的方法来完成。

下面是你需要的代码:

const data = new FormData(document.querySelector('form'));
const json = JSON.stringify(Array.from(data).reduce((o,[k,v])=>(o[k]=v,o),{}));

希望这能帮助到一些人。

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

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

如果需要支持序列化嵌套字段(类似于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>

这里有一种更函数化的方式,不需要使用库。

Array.from(formData.entries()).reduce((memo, [key, value]) => ({
  ...memo,
  [key]: value,
}), {});

例子:

. getelementbyid(“foobar”)。addEventListener('submit', (e) => { e.preventDefault (); const formData = new formData (e.target); const data = Array.from(formData.entries()).reduce((memo, [key, value]) => ({ 备忘录, (例子):值, }, {}); . getelementbyid(“输出”)。innerHTML = JSON.stringify(数据); }); <形式id =“foobar”> <input name='baz' /> <input type='submit' /> > < /形式 <pre id='output'>输入一些值并提交</pre>

在我的情况下,形式数据是数据,消防基地是期待一个对象,但数据包含对象以及所有其他东西,所以我尝试了数据。珍惜它的作用!!