saber 酱的抱枕

Fly me to the moon

12/20
2016
学习

使用HTML5的formData做ajax提交表单

我之前写过一篇《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-Typemultipart/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对象,其他现代浏览器均已支持。

使用HTML5的formData做ajax提交表单