我如何将条目从HTML5 FormData对象转换为JSON?
解决方案不应该使用jQuery。而且,它不应该简单地序列化整个FormData对象,而应该只序列化它的键/值条目。
我如何将条目从HTML5 FormData对象转换为JSON?
解决方案不应该使用jQuery。而且,它不应该简单地序列化整个FormData对象,而应该只序列化它的键/值条目。
当前回答
编辑:我看到已经有一个答案得出了非常相似的结果。
两个主要区别:
这不会将数值键作为数组下标,而是将它们视为对象键。可能不是正确的行为,但我个人从来没有写过使用这种符号的表单,可能会更新它。 这不是一个递归函数,这显然不是一个有利或不利的问题
忽略任何缺乏效率的问题。这将处理无限嵌套和数组的重复键。这显然不会转换文件之类的东西,但我不需要它,所以我没有添加它。
下面是一个JSFiddle的转换示例,可以用这个函数实现
一个很好的使用示例(这也是我的用例)是从html表单元素创建一个新的FormData对象,并轻松地将其转换为JSON进行发送。
/**
* @param {FormData} formData
* @return {Object}
*/
function formDataToObject(formData) {
const object = {};
for (let pair of formData.entries()) {
const key = pair[0];
const value = pair[1];
const isArray = key.endsWith('[]');
const name = key.substring(0, key.length - (2 * isArray));
const path = name.replaceAll(']', '');
const pathParts = path.split('[');
const partialsCount = pathParts.length;
let iterationObject = object;
for (let i = 0; i < partialsCount; i++) {
let part = pathParts[i];
let iterationObjectElement = iterationObject[part];
if (i !== partialsCount - 1) {
if (!iterationObject.hasOwnProperty(part) || typeof iterationObjectElement !== "object") {
iterationObject[part] = {};
}
iterationObject = iterationObject[part];
} else {
if (isArray) {
if (!iterationObject.hasOwnProperty(part)) {
iterationObject[part] = [value];
} else {
iterationObjectElement.push(value);
}
} else {
iterationObject[part] = value;
}
}
}
}
return object;
}
其他回答
我知道已经很晚了,但这是解决方案;
new URLSearchParams(new FormData(formElement)).toString()
这个可以作为正文发送。遗憾的是,它不是JSON。
多年后的香草ajs (es6)
let body = new FormData()
body.set('key1', 'value AA')
body.set('key2', 'value BB')
let data = [...body.keys()].reduce( (acc, key, idx) => {
acc[key] = body.get(key)
return acc
} , {} )
console.log(JSON.stringify(data)) // {key1: 'value AA', key2: 'value BB'}
我在这里迟到了。但是,我做了一个简单的方法来检查输入type="checkbox"
var formData = new FormData($form.get(0));
var objectData = {};
formData.forEach(function (value, key) {
var updatedValue = value;
if ($('input[name="' + key + '"]').attr("type") === "checkbox" && $('input[name="' + key + '"]').is(":checked")) {
updatedValue = true; // we don't set false due to it is by default on HTML
}
objectData[key] = updatedValue;
});
var jsonData = JSON.stringify(objectData);
我希望这能帮助到其他人。
这里有一种更函数化的方式,不需要使用库。
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>
使用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>