我如何将条目从HTML5 FormData对象转换为JSON?
解决方案不应该使用jQuery。而且,它不应该简单地序列化整个FormData对象,而应该只序列化它的键/值条目。
我如何将条目从HTML5 FormData对象转换为JSON?
解决方案不应该使用jQuery。而且,它不应该简单地序列化整个FormData对象,而应该只序列化它的键/值条目。
当前回答
简单易用的功能
我已经为此创建了一个函数
function FormDataToJSON(FormElement){
var formData = new FormData(FormElement);
var ConvertedJSON= {};
for (const [key, value] of formData.entries())
{
ConvertedJSON[key] = value;
}
return ConvertedJSON
}
示例使用
var ReceivedJSON = FormDataToJSON(document.getElementById('FormId'));
在这段代码中,我使用for循环创建了空JSON变量,我在每个迭代中都使用了从formData Object到JSON key的键。
你在GitHub上找到我的JS库中的此代码,如果需要改进,请建议我,我已经在这里放置了代码https://github.com/alijamal14/Utilities/blob/master/Utilities.js
其他回答
对于我的目的,包括多选,如复选框,这是很好的:
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 formDataToJson(f) {
return Object.fromEntries(Array.from(f.keys(), k =>
k.endsWith('[]') ? [k.slice(0, -2), f.getAll(k)] : [k, f.get(k)]));
}
例如,如果你有:
const f = new FormData();
f.append("a", "1");
f.append("a", "2");
f.append("b[]", "3");
f.append("b[]", "4");
formDataToJson(f) // --> produces {a: "1", b: ["3","4"]}
编辑:我看到已经有一个答案得出了非常相似的结果。
两个主要区别:
这不会将数值键作为数组下标,而是将它们视为对象键。可能不是正确的行为,但我个人从来没有写过使用这种符号的表单,可能会更新它。 这不是一个递归函数,这显然不是一个有利或不利的问题
忽略任何缺乏效率的问题。这将处理无限嵌套和数组的重复键。这显然不会转换文件之类的东西,但我不需要它,所以我没有添加它。
下面是一个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;
}
尽管来自@dzuc的答案已经很好了,你可以使用数组解构(在现代浏览器或Babel中可用)使它更优雅:
// original version from @dzuc
const data = Array.from(formData.entries())
.reduce((memo, pair) => ({
...memo,
[pair[0]: pair[1],
}), {})
// with array destructuring
const data = Array.from(formData.entries())
.reduce((memo,[key, value]) => ({
...memo,
[key]: value,
}), {})