FormData
接口提供了一种表示表单数据的键值对 key/value
的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send() 方法发送出去,本接口和此方法都相当简单直接。如果表单 enctype 属性设为 multipart/form-data ,则会使用表单的 submit() 方法来发送数据,从而发送数据具有同样形式。
构造函数
FormData()
构造函数用于创建一个新的FormData对象。
var formData = new FormData(form)
form
可选
一个HTML 上的``表单元素——当指定了,这种方式创建的FormData对象会自动将form中的表单值也包含进去,包括文件内容也会被编码之后包含进去。
例子
下面的代码将创建一个空的FormData对象:
var formData = new FormData(); // 当前为空
// 你可以使用FormData.append来添加键/值对到表单里面;
formData.append('username', 'yang');
或者你可以使用可选的form参数来创建一个带预置数据的FormData对象
:
<form id="myForm" name="myForm">
<div>
<label for="username">Enter name:</label>
<input type="text" id="username" name="username">
</div>
<div>
<label for="useracc">Enter account number:</label>
<input type="text" id="useracc" name="useracc">
</div>
<div>
<label for="userfile">Upload file:</label>
<input type="file" id="userfile" name="userfile">
</div>
<input type="submit" value="Submit!">
</form>
注意: 所有的输入元素都需要有name属性,否则无法访问到值。
vr formData = new FormData($("#myForm")[0]);
var name = formData.get("username"); // 获取名字
var psw = formData.get("useracc"); // 获取账户
// 当然也可以在此基础上,添加其他数据
formData.append("token","kshdfiwi3rh");
API
FormData.append()
通过append(key,value)
来添加数据,如果指定的key不存在则会新增一条数据,如果key存在,则追加到数据末尾
FormData.set
和 append()
的区别在于,如果指定的键已经存在, FormData.set
会使用新值覆盖已有的值,而 append()
会把新值添加到已有值集合的后面。
这个方法有两个版本:一个有两个参数的版本和一个有三个参数的版本。
// 语法
// name: value中包含的数据对应的表单名称
// value: 表单的值。可以是USVString 或 Blob (包括子类型,如 File)。
//filename (可选): 传给服务器的文件名称 (一个 USVString), 当一个 Blob 或 File 被作为第二个参数的时候, Blob 对象的默认文件名是 "blob"。 File 对象的默认文件名是该文件的名称。
formData.append(name, value);
formData.append(name, value, filename);
// 示例
var formData = new FormData(); // Currently empty
// 你可以通过 FormData.append 往对象里加入键值对:
formData.append('username', 'Chris');
formData.append('userpic', myFileInput.files[0], 'chris.jpg');
// 跟常规表单数据一样,你可以使用同一个名称添加多个值 。例如 (为了与PHP命名习惯一致在名称中添加了[]):
formData.append('userpic[]', myFileInput1.files[0], 'chris1.jpg');
formData.append('userpic[]', myFileInput2.files[0], 'chris2.jpg');
formData.getAll("userpic[]"); // [myFileInput1.files[0], myFileInput2.files[0]]
这项技术使得多文件上传的处理更加简单,因为所得数据结构更有利于循环。
FormData.get/getAll()
get()
方法用于返回FormData对象中和指定的键关联的第一个值,如果你想要返回和指定键关联的全部值,那么可以使用getAll()
方法。
getAll()
方法会返回该 FormData 对象指定 key 的所有值。
// 语法
// name: 将要获取值的键名
// 返回值: 包含值的FormDataEntryValue (en-US)。
formData.get(name);
// 例子
var formData = new FormData();
// 使用FormData.append方法添加两个数据:
formData.append('username', 'Chris');
formData.append('username', 'Bob');
// 获取key为name的第一个值
formData.get('username'); // "Chris"
// 返回一个数组,获取key为name的所有值
formData.getAll("username"); // ["Chris",'Bob']
FormData.delete()
delete()
方法会从 FormData
对象中删除指定键,即 key,和它对应的值,即 value
// 语法
// name: 要删除的键(Key)的名字
formData.delete(name);
// 例子
var formData = new FormData(myForm);
formData.delete('username');
FormData.set()
给 FormData
设置属性值,如果FormData
对应的属性值存在则覆盖原值,否则新增一项属性值。
// 语法
// name: 字段名称
// value:字段的值,如果是传入两个参数的方式,那么该值是一个 USVString,如果不是,将被转成一个字符串。如果是传入三个参数的方式,那么该值将是一个布尔值(Blob),文件(File),或者一个 USVString,如果不是,将被转成一个字符串。
// filename(可选): 当第二个参数传递的是一个blob对象(Blob)或者file对象(File),filename参数就代表传给服务端的文件名(一个USVString)。Blob 对象的默认文件名是 "blob"。
// 该方法有两种使用方式,一个是传入两个参数,一个是传入三个参数。
formData.set(name, value);
formData.set(name, value, filename);
// 示例
var formData = new FormData(); // Currently empty
formData.set('username', 'Chris');
formData.set('userpic', myFileInput.files[0], 'chris.jpg');
FormData.has()
has()
方法会返回一个布尔值,表示该FormData对象是否含有某个key
// 语法
formData.has(name);
// 示例
var formData = new FormData();
formData.has('username'); // false
formData.append('username', 'Chris');
formData.has('username'); // true
FormData.entries()
FormData.entries()
方法返回一个 iterator对象 ,此对象可以遍历访问FormData中的键值对。其中键值对的key是一个 USVString 对象;value是一个 USVString , 或者 Blob对象。
// 语法
formData.entries();
// 示例
// Create a test FormData object
var formData = new FormData();
formData.append('key1', 'value1');
formData.append('key2', 'value2');
// 每调用一次next()返回一条数据,数据的顺序由添加的顺序决定
// 返回的是一个对象,当其done属性为true时,说明已经遍历完所有的数据,这个也可以作为判断的依据
// 返回的对象的value属性以数组形式存储了一对key/value,数组下标0为key,下标1为value,如果一个key值对应多个value,会变成多对key/value返回
var i = formData.entries();
i.next(); // {done:false, value:["key1", "value1"]}
i.next(); // {done:fase, value:["key2", "value2"]}
i.next(); // {done:true, value:undefined}
// 方式二
for(var pair of formData.entries()) {
console.log(pair[0]+ ', '+ pair[1]);
}
key1, value1
key2, value2
FormData.keys()
FormData.keys()
该方法返回一个迭代器(iterator),遍历了该 formData 包含的所有key ,这些 key 是 USVString 对象。
// 语法
// 返回值:返回一个迭代器( iterator)
formData.keys();
// 示例
// 先创建一个 FormData 对象
var formData = new FormData();
formData.append('key1', 'value1');
formData.append('key2', 'value2');
// 输出所有的 key
for (var key of formData.keys()) {
console.log(key);
}
key1
key2
FormData.values()
FormData.values()
方法返回一个允许遍历该对象中所有值的 迭代器 。这些值是 USVString 或是Blob 对象。
// 语法
// 返回值:返回一个迭代器
formData.values();
// 示例
//创建一个FormData测试对象
var formData = new FormData();
formData.append('key1', 'value1');
formData.append('key2', 'value2');
//显示值
for (var value of formData.values()) {
console.log(value);
}
value1
value2
FormData 实践
FormData 对象的使用:
-
用一些键值对来模拟一系列表单控件:把 form 中所有表单元素的 name 与 value 组装成一个 queryString;
-
异步上传二进制文件;
FormData 对象的操作方法,全部在原型中本身没任何的属性及方法
使用 FormData 对象发送文件
<!--HTML部分-->
<form action="">
<label for="">
姓名: <input type="text" name="name">
</label>
<label for="">
文件:<input id="file" type="file" name="file">
</label>
<label for="">
<input type="button" value="保存">
</label>
</form>
原生ajax
//原生js上传文件
//获取按钮
var btn = document.querySelector('[type=button]');
//绑定事件
btn.onclick = function () {
// 文件元素
var file = document.querySelector('[type=file]');
// 通过FormData将文件转成二进制数据
var formData = new FormData();
// 将文件转二进制
formData.append('upload', file.files[0]);
//创建XMLHttpRequest,用这个来发送数据
var xhr = new XMLHttpRequest;
/*初始化HTTP请求参数(请求方式,url,是否同步)*/
xhr.open('post', 'file.php');
/*
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
设置请求头的contentType
*/
// 监听上传进度
xhr.upload.onprogress = function (ev) {
// 事件对象
// console.log(ev);
var percent = (ev.loaded / ev.total) * 100 + '%';
console.log(percent);
progress.style.width = percent;
}
xhr.send(formData);
xhr.onreadystatechange = function () {
//status状态为200 表示请求成功,readystate为4表示对象传递完毕或者准备就绪
if(xhr.readyState == 4 && xhr.status == 200) {
}
}
}
使用 jQuery
//绑定提交事件
function upload() {
//获取form表单元素
var f = document.getElementById("myForm");
//使用表单元素来构造FromData
var myform = new FormData(f);
$.ajax({
url: "/Library/test/upload",
type: "post",
dataType: "json",
data: myform,
cache: false, // 不缓存
processData: false, // jQuery不要去处理发送的数据
contentType: false, // jQuery不要去设置Content-Type请求头
success: function (data) {
console.log(data);
}
});
}