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

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


当前回答

我认为这是从一个formData formData对象中得到你想要的结果的最简单的方法:

const jsonData = {};

for(const [key, value] of formData) {
    jsonData[key] = value;
}

其他回答

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

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

我在这里迟到了。但是,我做了一个简单的方法来检查输入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);

我希望这能帮助到其他人。

编辑:我看到已经有一个答案得出了非常相似的结果。

两个主要区别:

这不会将数值键作为数组下标,而是将它们视为对象键。可能不是正确的行为,但我个人从来没有写过使用这种符号的表单,可能会更新它。 这不是一个递归函数,这显然不是一个有利或不利的问题

忽略任何缺乏效率的问题。这将处理无限嵌套和数组的重复键。这显然不会转换文件之类的东西,但我不需要它,所以我没有添加它。

下面是一个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;
}

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

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>

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

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)
}