一、简介
通常情况下,前端在使用post
请求提交数据的时候,请求都是采用application/json
或 application/x-www-form-urlencoded
编码类型,分别是借助JSON
字符串来传递参数或者key=value
格式字符串(多参数通过&
进行连接)来传递参数,确实足以覆盖大多数业务场景。但是在文件上传等特殊业务场景下,这两种编码类型就有些捉襟见肘了,例如选择JSON
字符串传递参数,在使用JSON.stringify()
格式化参数数据时,会将File
和Blob
对象转化成{}
,文件数据会丢失。所以此时我们就需要使用第三种编码类型multipart/form-data
,使用FormData
对象来传递参数。
FormData
提供了一种以 key/value
键值对集合表示表单数据的数据构造方式,通过该方式我们可以将file
、blob
等不易传输的数据通过 ajax
请求轻松的发送到服务器端。
当使用FormData
对象作为参数时,无需手动设置请求的编码类型,浏览器会自动将请求的编码类型Content-type
设置为multipart/form-data
。
浏览器兼容性:
二、相关方法
1、FormData()
FormData([form])
方法是FormData
对象的构造函数,用来创建一个新的FormData
对象。
// 创建空的 FormData 对象
const formData = new FormData()
该方法拥有一个可选参数form
,值为页面HTML中的一个<form>
表单元素,当设置该参数时,创建的FormData
对象将自动的将form表单中的值包含进去,包括file
文件内容也会被编码之后包含进去。但是要注意给表单中所有的输入元素(<input>
、<textarea>
)设置name
属性,否则无法被FormData
对象包含,输入元素的name
属性将会成为FormData
对象中数据键值对的key
,输入元素的值将会成为对应的value
。
<!-- form表单元素 -->
<form action="#" id="form1">
<div>
<label for="name">姓名:</label>
<input type="text" id="name" name="name">
</div>
<div>
<label for="age">年龄:</label>
<input type="text" id="age" name="age">
</div>
<div>
<label for="sex">性别:</label>
<!-- 未设置name属性不会被 formData 包含 -->
<input type="text" id="sex">
</div>
</form>
<br />
<button onclick="logFormData()">输出formData对象</button>
<script>
// 输出 FormData 对象的数据
function logFormData () {
// 获取表单元素
const form = document.getElementById('form1')
// 创建带有预置数据的 FormData 对象
const formData = new FormData(form)
// 输出formData对象中的所有键值对
for (var pair of formData.entries()) {
console.log(pair[0] + '----' + pair[1]);
}
}
</script>
执行结果:
2、FormData.append()
FormData.append(name,value,[filename])
方法用于向FormData
对象中添加一个新的值,该方法拥有两个必选参数name
和value
,以及一个可选参数filename
。name
对应FormData
对象中键值对数据的key
,value
对应键值对数据的值。如果name
这个key
在FormData
中已经存在,则会将新值value
添加到原有值集合的后面,先添加的值在前面,后添加的值在后面,多个值同时以集合的形式存在;如果name
这个key在FormData
中不存在,则会新增这个key
,并赋予对应的值value
。
// 创建空的 FormData 对象
const formData = new FormData()
// 添加一个键值对 此时并不存在对应的key 会新增这个key
formData.append('name', '张三')
// 给同一个key 再次添加值
formData.append('name', '李四')
// 输出这个key对应的所有value值
console.log("formData.getAll('name')----", formData.getAll('name'));
执行结果:
可选参数filename
是当第二个参数value
为Blob
或file
文件数据时,设置传给服务器端的文件名称。如果不设置该参数,则Blob
类型默认文件名为blob
,file
类型的默认文件名为文件本身的名称。
// 创建空的 FormData 对象
const formData = new FormData()
// 添加一个file键值对数据 取默认文件名称
formData.append('file', file)
// 添加一个file键值对数据 并设置文件名称
formData.append('file', file, 'test.png')
// 输出这个key对应的所有value值
console.log("formData.getAll('file')----", formData.getAll('file'));
执行结果2:
3、FormData.set()
FormData.set(name,value,[filename])
方法与FormData.append()
方法类似,都是用于向FormData
对象中添加一个新的值,如果name
这个key在FormData
中不存在,则会新增这个key
,并赋予对应的值value
;但是如果name
这个key在FormData
中已经存在,那么该方法会直接覆盖掉原来的value
,无论原有值集合有几个数据,全都被覆盖。
其余用法与FormData.append()
方法相同。
// 创建空的 FormData 对象
const formData = new FormData()
// 使用append()添加一个键值对 此时并不存在对应的key 会新增这个key
formData.append('name', '张三')
// 使用append()给同一个key 再次添加值
formData.append('name', '李四')
// 输出这个key对应的所有value值
console.log("append()两次数据后----", formData.getAll('name'));
// 使用set()给同一个key 设置值 会覆盖之前的值
formData.set('name', '王五')
// 输出这个key对应的所有value值
console.log("set()一次数据后----", formData.getAll('name'));
执行结果:
4、FormData.delete()
FormData.delete(name)
方法用于从FormData
对象中删除name
这个key
及其对应的所有value
。
// 创建空的 FormData 对象
const formData = new FormData()
// 使用append()添加一个键值对 此时并不存在对应的key 会新增这个key
formData.append('name', '张三')
// 使用append()给同一个key 再次添加值
formData.append('name', '李四')
// 输出这个key对应的所有value值
console.log("append()两次数据后----", formData.getAll('name'));
// 使用delete()删除一个key及其所有的value
formData.delete('name')
// 再次输出这个key
console.log("delete()删除一次后----", formData.getAll('name'));
执行结果:
5、FormData.entries()
FormData.entries()
方法用于获取一个由FormData
对象中所有键值对组成的iterator(迭代器)
对象,然后通过该对象可以遍历访问所有的键值对数据。
该方法获取的iterator(迭代器)
对象,需要通过for...of..
的形式来进行遍历,每个遍历元素都是数组类型,数组中有两个元素,第一个为key
,另一个为value
。如果FormData
对象中的某个key
有多个value
,则该key
会被遍历多次,每次只对应一个value
。
// 创建空的 FormData 对象
const formData = new FormData()
// 使用append()添加一个键值对
formData.append('name', '张三')
// 使用append()给同一个key 再次添加值
formData.append('name', '李四')
// 使用append()添加另外一个键值对
formData.append('sex', '男')
// 获取迭代器对象
const entries = formData.entries()
// 输出迭代器对象
console.log('entries-----', entries);
// 遍历迭代器对象
for (var pair of entries) {
// 输出遍历元素
console.log('pair---', pair);
// 输出元素的key和value
console.log(pair[0] + '----' + pair[1]);
}
执行结果:
除了该方法外,我们还可以通过for...of..
形式直接遍历FormData
对象,其作用与结果与该方法完全相同:
// 创建空的 FormData 对象
const formData = new FormData()
// 使用append()添加一个键值对
formData.append('name', '张三')
// 使用append()给同一个key 再次添加值
formData.append('name', '李四')
// 使用append()添加另外一个键值对
formData.append('sex', '男')
// 遍历formData对象
for (var pair of formData) {
console.log('当前遍历元素---', pair);
console.log(pair[0] + '----' + pair[1]);
}
执行结果2:
6、FormData.keys()
FormData.keys()
方法用于获取一个由FormData
对象中所有键值对中的key
组成的iterator(迭代器)
对象,然后通过该对象可以遍历访问所有的key
,类型为String
。与entries()
方法相同的是:如果FormData
对象中的某个key
有多个value
,则该key
会被遍历多次,每次对应一个value
。
// 创建空的 FormData 对象
const formData = new FormData()
// 使用append()添加一个键值对
formData.append('name', '张三')
// 使用append()给同一个key 再次添加值
formData.append('name', '李四')
// 使用append()添加另外一个键值对
formData.append('sex', '男')
// 获取key组成的迭代器对象
const keys = formData.keys()
// 输出迭代器对象
console.log('keys-----', keys);
// 遍历迭代器对象
for (var key of keys) {
console.log('key---', key);
}
执行结果:
7、FormData.values()
FormData.values()
方法用于获取一个由FormData
对象中所有键值对中的value
组成的iterator(迭代器)
对象,然后通过该对象可以遍历访问所有的value
,类型为String
、File
、Blob
。如果FormData
对象中的某个key
有多个value
,则每个value
都会遍历一次。
// 创建空的 FormData 对象
const formData = new FormData()
// 使用append()添加一个键值对
formData.append('name', '张三')
// 使用append()给同一个key 再次添加值
formData.append('name', 333444)
// 使用append()添加另外一个键值对
formData.append('sex', '男')
// 获取value组成的迭代器对象
const values = formData.values()
// 输出迭代器对象
console.log('values-----', values);
// 遍历迭代器对象
for (var value of values) {
console.log('value---', value);
}
执行结果:
8、FormData.has()
FormData.has()
该方法用于判断FormData
对象中是否含有某个key
,返回值为一个布尔值。
// 创建空的 FormData 对象
const formData = new FormData()
// 使用append()添加一个键值对
formData.append('name', '张三')
// 使用append()添加另外一个键值对
formData.append('sex', '男')
// 使用has()判断是否存在某个key
console.log('has()判断是否存在name---', formData.has('name'));
// 使用delete()删除一个key及其所有的value
formData.delete('sex')
// 使用has()判断一个已经被删除的key
console.log('has()判断被delete()删除的sex---', formData.has('sex'));
// 使用has()判断一个不存在的key
console.log('has()判断不存在的age---', formData.has('age'));
执行结果:
9、FormData.get()
FormData.get(name)
方法用于获取FormData
对象中name
这个key
所对应的value
集合里的第一个value
,value
集合中值的顺序,按照添加的顺序进行排序。
// 创建空的 FormData 对象
const formData = new FormData()
// 使用append()添加一个键值对
formData.append('name', '张三')
// 使用append()给同一个key 再次添加值
formData.append('name', 333)
// 使用append()添加另外一个键值对
formData.append('sex', '男')
// 使用get()获取name对应的第一个value
console.log('get()获取name对应的第一个value---', formData.get('name'));
// 使用get()获取sex对应的第一个value
console.log('get()获取sex对应的第一个value---', formData.get('sex'));
执行结果:
10、FormData.getAll()
FormData.getAll()
方法用于获取FormData
对象中name
这个key
所对应的value
集合,value
集合中值的顺序,按照添加的顺序进行排序。
// 创建空的 FormData 对象
const formData = new FormData()
// 使用append()添加一个键值对
formData.append('name', '张三')
// 使用append()给同一个key 再次添加值
formData.append('name', 333)
// 使用append()添加另外一个键值对
formData.append('sex', '男')
// 使用getAll()获取name对应的value集合
console.log('getAll()获取name对应的value集合---', formData.getAll('name'));
// 使用getAll()获取sex对应的value集合
console.log('getAll()获取sex对应的value集合---', formData.getAll('sex'));
执行结果:
三、相关资料
FormData
form