参考地址:https://developer.mozilla.org/zh-CN/docs/Web/API/FormData

FormData 接口提供了一种表示表单数据的键值对 key/value 的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send() 方法发送出去,本接口和此方法都相当简单直接。如果送出时的编码类型被设为 “multipart/form-data”,它会使用和表单一样的格式。

一、构造函数

FormData()构造函数用于创建一个新的FormData对象。
语法:

  1. var formData = new FormData(form)

参数:

form(可选) 一个HTML 上的<form>表单元素——当指定了,这种方式创建的FormData对象会自动将form中的表单值也包含进去,包括文件内容也会被编码之后包含进去。

测试1:通过表单创建FormData对象

HTML代码:

<form id="form-data">
        <span>用户名:</span>
        <input name="username" type="text">
        <span>密码:</span>
        <input name="password" type="password">
    </form>
    <button id="new-form-data">使用form创建一个FormData对象</button>

js代码:

//测试FormData构造方法的开始 var formData = new FormData(form) form可选
    var form = document.getElementById("form-data");
    var newFormData = document.getElementById("new-form-data");

    newFormData.addEventListener("click", function() {
        var formData = new FormData(form); //通过form创建 FormData对象,次对象可以直接通过 xhr send 发送到后台
        console.log(formData); 
        console.log("username:" + formData.get("username"))
        console.log("password:" + formData.get("password"))
    });

控制台输出:
image.png
以上测试可以看出,使用FormData 可以直接将 form 中的数据转成一个FormData 对象,并且这个对象在浏览器直接打印的话是看不到任何表单信息的。可以通过 get 方法来获取对应的值。
注: 表单中一定要调价 name 属性

测试2:直接new创建对象,再append k/v

var newEmptyFormData = document.getElementById("new-empty-form-data");
newEmptyFormData.addEventListener("click", function() {
        var formData = new FormData(); //创建一个空的 FormData对象
        formData.append("username", "zhangsan");
        formData.append("password", "123456")
        console.log(formData);
        console.log(formData.get("username"))
        console.log(formData.get("password"))
    });

二、增、删、改方法

2.1 append()

append() 方法 会添加一个新值到 FormData 对象内的一个已存在的键中如果键不存在则会添加该键。
set() 和 append() 的区别在于,如果指定的键已经存在, FormData.set 会使用新值覆盖已有的值,而 append() 会把新值添加到已有值集合的后面。
语法:

formData.append(name, value);
formData.append(name, value, filename);

参数:

name 数据的建 k 的名称,通常来说用 String ,非要使用对象,也不报错。
value 表单的值。可以是USVString(简单理解成String)或Blob(包括子类,如File)
filename(可选) 当一个 BlobFile 被作为第二个参数的时传给服务器的文件名称(USVString)。 Blob 对象的默认文件名是 “blob”; File 对象的默认文件名是该文件的名称。

测试1:使用对象最为key (没什么意义,玩玩)

//测试使用对象最为key
        var formData = new FormData(); //创建一个空的 FormData对象
        var key = {name: "test"}
        var keySame = {name: "test"}
        formData.append(key, 123); //key值给一个对象

        console.log(formData.get(key))  //可以取出 值 123
        console.log(formData.get(keySame)) //可以取出 值 123 , 说明不是使用 对象的地址
        console.log(key === keySame) //false
        console.log(formData.get('{name: "test"}'))  //null, 说明不是简单讲对象转字符串

image.png

测试2:正常使用key为String。两个参数 append(name, value)

以下测试可以看出,不能直接在 value 中放一个对象,放对象进去取回来时为 [object Object]

//测试key为String,value为Number、String、Object
        var formData = new FormData(); //创建一个空的 FormData对象
        var objValue = {name: "张三"};
        formData.append("string", "value为String");
        formData.append("number", 12);
        formData.append("object", objValue);

        console.log("string:" + formData.get("string"))  // value为String
        console.log("number:" + formData.get("number")) // 12
        console.log("object:" + formData.get("object")) // [object Object]
        console.log("object:" + formData.get("object").name) //undefined

image.png

测试3:三个参数 append(name, value, filename)

当给第三个参数时,文件的名字为第三个参数。当不给第三个参数时,value 为 File 则 文件名为原始的文件名,value 为Blob 则 文件名为 blob。

//测试使用 File 或 Blob
        var file = $("#append-file")[0].files[0]; //从input框中拿到一个文件对象
        var formData = new FormData(); //创建一个空的 FormData对象
        formData.append("file_give_name", file, "appendFile.jpg");
        formData.append("file_not_give_name", file);
        formData.append("blob", new Blob())

        var file_give_name = formData.get("file_give_name");
        var file_not_give_name = formData.get("file_not_give_name");
        var blob = formData.get("blob");
        console.log("file_give_name:",file_give_name.name); // appendFile.jpg
        console.log("file_not_give_name:",file_not_give_name.name); // iron-man.jpg (文件原本的名字)
        console.log("blob:",blob.name); // blob

image.png

测试4:添加多个值

添加多个值时,使用get方法始终只能够得到第一个值,使用 values(name) 方法将会返回一个迭代器,可以遍历所有的值。values 方法后面介绍。

//测试添加多个值
        var formData = new FormData(); //创建一个空的 FormData对象
        formData.append("more_then_one", "firstValue");
        formData.append("more_then_one", "secondVlaue");

        console.log("more_then_one:",formData.get("more_then_one"));  //拿到的是第一个值
        console.log("more_then_one:",formData.get("more_then_one"));  //多次调用get拿到的还是第一个值
        console.log("more_then_one:",formData.values("more_then_one")); //返回一个 Iterator 对象(迭代器)

image.png

2.2 delete()

delete() 方法会从 FormData 对象中删除指定键,即 key,和它对应的值,即 value。
语法:

formData.delete(name);

参数:

name 要删除的键(Key)的名字。

测试1: 删除只有一个值 和 又多个值得key

删除又一个或多个值得,值都被删除。

        var formData = new FormData(); //创建一个空的 FormData对象
        formData.append("one_value", "只有一个值");
        formData.append("more_then_one", "第一个值");
        formData.append("more_then_one", "第二个值");

        formData.delete("one_value");
        formData.delete("more_then_one");

        console.log("one_value:", formData.get("one_value"));//null
        console.log("more_then_one:", formData.get("more_then_one"))//null

image.png

2.3 set()

set() 方法会对 FormData 对象里的某个 key 设置一个新的值,如果该 key 不存在,则添加。
set() 和 FormData.append 不同之处在于:如果某个 key 已经存在,set() 会直接覆盖所有该 key 对应的值,而 FormData.append 则是在该 key 的最后位置再追加一个值。

测试1:改值

        var formData = new FormData(); //创建一个空的 FormData对象
        formData.append("one_value", "只有一个值");
        console.log("one_value:", formData.get("one_value"));

        formData.set("one_value", "改之后的值");
        console.log("one_value:", formData.get("one_value"))

image.png

三、查询的方法

3.1 get()

get()方法用于返回FormData对象中和指定的键关联的第一个值,如果你想要返回和指定键关联的全部值,那么可以使用getAll()方法。
语法

formData.get(name);

参数:

name 将要获取值的键名

返回值:
包含值的FormDataEntryValue。

3.2 getAll()

getAll()方法会返回该 FormData 对象指定 key 的所有值。
语法

formData.getAll(name);

参数:

name 将要获取值的键名

返回值:
一个 FormDataEntryValue 数组

测试:

        var formData = new FormData(); //创建一个空的 FormData对象
        formData.append("get_all", "firstValue");
        formData.append("get_all", "secondValue");
        console.log("get_all:", formData.getAll("get_all"))

image.png

3.3 has()

has()方法会返回一个布尔值,表示该FormData对象是否含有某个key 。
语法

formData.has(name);

参数:

name 将要获取值的键名

返回值:
一个 Boolean。

var formData = new FormData();
formData.has('username'); // Returns false
formData.append('username', 'Chris');
formData.has('username'); // Returns true

四、遍历的方法

4.1 entries()

entries() 方法返回一个 iterator对象 ,此对象可以遍历访问FormData中的键值对。其中键值对的key是一个 USVString 对象;value是一个 USVString , 或者 Blob对象。
语法

formData.entries();

参数:
没有参数
返回值:
返回 iterator(迭代器)。

测试:entries

注:entries 返回一个迭代器对象。关于迭代器的内容见 @TODO 待学习后补充,应该会放在 原生js的文件夹

        var formData = new FormData(); //创建一个空的 FormData对象
        formData.append("one", "one的值");
        formData.append("two", "two的值");
        var entries = formData.entries();

        for (var entry of entries) {
            var key = entry[0];
            var value = entry[1];
            console.log(key, value)
        }

image.png

4.2 keys()

keys() 该方法返回一个迭代器(iterator),遍历了该 formData 包含的所有key ,这些 key 是 USVString 对象。
语法

formData.keys();

参数:
没有参数
返回值:
返回 iterator(迭代器)。

测试:keys

        var formData = new FormData(); //创建一个空的 FormData对象
        formData.append("one", "one的值");
        formData.append("two", "two的值");

        var keys = formData.keys();
        for (var key of keys) {
            console.log(key)
        }

image.png

4.3 values()

values() 方法返回一个允许遍历该对象中所有值的 迭代器 。这些值是 USVString 或是Blob 对象
语法

formData.values();

参数:
没有参数
返回值:
返回 iterator(迭代器)。

测试:values

如果一个 key 有多个 value ,所有的 value 都可以遍历到

        var formData = new FormData(); //创建一个空的 FormData对象
        formData.append("one", "one的值");
        formData.append("two", "two的值");
        formData.append("two", "two的第二个值");

        var values = formData.values();
        for (var value of values) {
            console.log(value)
        }

image.png