我之前写过一篇《JavaScript表单序列化》的文章,表单序列化可以方便我们使用ajax来提交表单数据,避免网页刷新。我在这篇文章的末尾也附上了示例代码。但是使用表单序列化也有不太方便的地方:
第一,需要额外的代码来做表单序列化;
第二,需要在请求头里规定表单数据的格式。我第一次使用的时候因为不知道加这个就出错了。而且这个格式还有好几种。
第三,有很多用原生js做的表单序列化代码不能通过ajax提交附件。jquery的表单序列化可以,但也有点麻烦。
现在,HTML5的formData将上面的问题全部解决了,进一步简化了使用ajax提交表单的步骤。
当点击提交按钮时,通过 Fetch 发送数据:
const formData = new FormData(document.querySelector("#formID")); //生成formData
fetch(url, {
method: 'post',
body: formData,
})
.then(…)
不过在默认情况下,用 Fetch 发出去的 FormData 的 Content-Type
是 multipart/form-data
。在后端进行处理时要注意这一点。
如果想改为 application/x-www-form-urlencoded
类型的话,可以通过 header 设置:
fetch(url, {
method: 'post',
body: formData,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
})
.then(…)
如果想把类型改为 application/json
,除了要设置 header,还需要把 FormData 转换为 JSON 对象才行。因为 FormData 不能直接当普通对象用。
直接输出 FormData 的话只能看到一个空对象,可以通过遍历输出它里面的 key 和 value:
for (const data of formData) {
console.log(data)
}
for (const [key, value] of formData) {
console.log(key, value)
}
所以可以通过遍历把 FormData 转换为 JSON 对象:
const obj = {}
for (const [key, value] of formData) {
obj[key] = value
}
console.log(obj)
上例中没有写发送附件该怎么做,其实很简单,要用到formData对象的append方法。formData对象的append方法可以通过添加键值对来追加内容。附件就是要用append方法添加进表单的formData里。
假如表单里有个file控件,我们要传递它,那么在上面代码里的new formData下面追加这个file控件的附件即可:
formData.append('file',document.querySelector("#formID input[type=file]").files[0]);
之后用ajax发送表单时会把附件也一并发送。
如果有必要,我们也可以创建一个空的formData对象,全部使用append方法添加内容。
var formData = new FormData();
formData.append("name", "value");
formData.append("a", 1);
formData.append("b", 2);
兼容性:IE浏览器从IE10开始支持formData对象,其他现代浏览器均已支持。
好腻害的二狗子