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

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


当前回答

另一种适用于选择多个或具有相同name属性的输入的方法:

function form_to_json() { const form_data = new FormData(document.querySelector('form')) const uniqueKeys = [...new Set(form_data.keys())] const obj = {} uniqueKeys.forEach((value, key) => { obj[value] = (form_data.getAll(value).length > 1) ? form_data.getAll(value) : form_data.get(value) }) const json = JSON.stringify(obj) alert(json) } <form> <input type="text" name="name" value="Cesar"></br> <select name="cars" id="cars" multiple> <option value="volvo" selected>Volvo</option> <option value="saab" selected>Saab</option> </select> <input type="button" onclick="form_to_json()" value="Ok"> </form>

其他回答

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

const jsonData = {};

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

你也可以直接在FormData对象上使用forEach:

var object = {};
formData.forEach(function(value, key){
    object[key] = value;
});
var json = JSON.stringify(object);

更新:

对于那些喜欢使用ES6箭头函数的相同解决方案的人:

var object = {};
formData.forEach((value, key) => object[key] = value);
var json = JSON.stringify(object);

更新2:

对于那些想要支持多选择列表或其他具有多个值的表单元素的人(因为关于这个问题的答案下面有很多评论,我将添加一个可能的解决方案):

var object = {};
formData.forEach((value, key) => {
    // Reflect.has in favor of: object.hasOwnProperty(key)
    if(!Reflect.has(object, key)){
        object[key] = value;
        return;
    }
    if(!Array.isArray(object[key])){
        object[key] = [object[key]];    
    }
    object[key].push(value);
});
var json = JSON.stringify(object);

这里用一个简单的多选择列表演示了这种方法的使用。

更新3:

这里要补充一点,如果将表单数据转换为json的目的是通过XML HTTP请求将其发送到服务器,则可以直接发送FormData对象而无需转换它。就这么简单:

var request = new XMLHttpRequest();
request.open("POST", "http://example.com/submitform.php");
request.send(formData);

参考MDN上使用FormData对象:

更新4:

正如下面我回答的一个评论中提到的,JSON stringify方法不会对所有类型的对象开箱即用。关于支持的类型的更多信息,我想参考JSON.stringify MDN文档中的描述部分。

在描述中还提到:

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

这意味着您可以提供自己的toJSON序列化方法,其中包含序列化自定义对象的逻辑。这样,您就可以快速轻松地为更复杂的对象树构建序列化支持。

多年后的香草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'}

你可以试试这个

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()中描述的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>