如何将条目从 HTML5FormData
对象转换为 JSON?
该解决方案不应使用 jQuery。此外,它不应简单地序列化整个FormData
对象,而应仅序列化其键/值条目。
如何将条目从 HTML5FormData
对象转换为 JSON?
该解决方案不应使用 jQuery。此外,它不应简单地序列化整个FormData
对象,而应仅序列化其键/值条目。
您也可以直接forEach
在FormData
对象上使用:
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);
对于那些想要支持多选列表或其他具有多个值的表单元素的人(因为关于这个问题的答案下面有很多评论,我将添加一个可能的解决方案):
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);
这里有一个 Fiddle,通过一个简单的多选列表演示了这种方法的使用。
作为结束这里的人的旁注,如果将表单数据转换为 json 的目的是通过 XML HTTP 请求将其发送到服务器,您可以FormData
直接发送对象而无需转换它。就这么简单:
var request = new XMLHttpRequest();
request.open("POST", "http://example.com/submitform.php");
request.send(formData);
正如我的回答下面的评论之一中提到的,JSONstringify
方法不适用于所有类型的对象。对于什么类型的支持的详细信息,我想指的描述部分的MDN文档JSON.stringify
。
在描述中还提到:
如果该值具有 toJSON() 方法,则它负责定义将序列化的数据。
这意味着您可以为您自己的toJSON
序列化方法提供用于序列化自定义对象的逻辑。这样,您可以快速轻松地为更复杂的对象树构建序列化支持。
2019年,这样的任务变得超级简单。
JSON.stringify(Object.fromEntries(formData));
Object.fromEntries
:支持 Chrome 73+、Firefox 63+、Safari 12.1
这是一种以更具功能性的风格完成的方法,而无需使用库。
Array.from(formData.entries()).reduce((memo, pair) => ({
...memo,
[pair[0]]: pair[1],
}), {});
例子:
document.getElementById('foobar').addEventListener('submit', (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const data = Array.from(formData.entries()).reduce((memo, pair) => ({
...memo,
[pair[0]]: pair[1],
}), {});
document.getElementById('output').innerHTML = JSON.stringify(data);
});
<form id='foobar'>
<input name='baz' />
<input type='submit' />
</form>
<pre id='output'>Input some value and submit</pre>
如果您有多个同名条目,例如,如果您使用<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
或entries
on 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 );
}
您可以通过使用FormData()对象来实现这一点。这个 FormData 对象将使用表单的当前键/值填充,使用键的每个元素的 name 属性和它们提交的值的值。它还将对文件输入内容进行编码。
例子:
var myForm = document.getElementById('myForm');
myForm.addEventListener('submit', function(event)
{
event.preventDefault();
var formData = new FormData(myForm),
result = {};
for (var entry of formData.entries())
{
result[entry[0]] = entry[1];
}
result = JSON.stringify(result)
console.log(result);
});