我如何将条目从HTML5 FormData对象转换为JSON?
解决方案不应该使用jQuery。而且,它不应该简单地序列化整个FormData对象,而应该只序列化它的键/值条目。
我如何将条目从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>
其他回答
我在这里迟到了。但是,我做了一个简单的方法来检查输入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(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序列化方法,其中包含序列化自定义对象的逻辑。这样,您就可以快速轻松地为更复杂的对象树构建序列化支持。
我知道已经很晚了,但这是解决方案;
new URLSearchParams(new FormData(formElement)).toString()
这个可以作为正文发送。遗憾的是,它不是JSON。
如果你有多个相同名称的条目,例如如果你使用<SELECT multiple>或有多个<INPUT type="checkbox">具有相同的名称,你需要注意这一点,并将值创建一个数组。否则只能得到最后选中的值。
以下是es6的现代版本:
function formToJSON( elem ) {
let output = {};
new FormData( elem ).forEach(
( value, key ) => {
// Check if property already exist
if ( Object.prototype.hasOwnProperty.call( output, key ) ) {
let current = output[ key ];
if ( !Array.isArray( current ) ) {
// If it's not an array, convert it to an array.
current = output[ key ] = [ current ];
}
current.push( value ); // Add the new value to the array.
} else {
output[ key ] = value;
}
}
);
return JSON.stringify( output );
}
稍旧的代码(但IE11仍然不支持,因为它不支持ForEach或FormData上的条目)
function formToJSON( elem ) {
var current, entries, item, key, output, value;
output = {};
entries = new FormData( elem ).entries();
// Iterate over values, and assign to item.
while ( item = entries.next().value )
{
// assign to variables to make the code more readable.
key = item[0];
value = item[1];
// Check if key already exist
if (Object.prototype.hasOwnProperty.call( output, key)) {
current = output[ key ];
if ( !Array.isArray( current ) ) {
// If it's not an array, convert it to an array.
current = output[ key ] = [ current ];
}
current.push( value ); // Add the new value to the array.
} else {
output[ key ] = value;
}
}
return JSON.stringify( output );
}