我如何将条目从HTML5 FormData对象转换为JSON?
解决方案不应该使用jQuery。而且,它不应该简单地序列化整个FormData对象,而应该只序列化它的键/值条目。
我如何将条目从HTML5 FormData对象转换为JSON?
解决方案不应该使用jQuery。而且,它不应该简单地序列化整个FormData对象,而应该只序列化它的键/值条目。
当前回答
的一行程序!
Array.from(fd).reduce((obj, [k, v]) => ({...obj, [k]: v}), {});
今天我了解到firefox有对象扩展支持和数组解构!
其他回答
你也可以直接在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序列化方法,其中包含序列化自定义对象的逻辑。这样,您就可以快速轻松地为更复杂的对象树构建序列化支持。
另一种适用于选择多个或具有相同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>
使用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>
我在这里迟到了。但是,我做了一个简单的方法来检查输入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);
我希望这能帮助到其他人。
多年后的香草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'}