【js】FormData作用和用法

作用

对象的使用:

  • 用一些键值对来模拟一系列表单控件,以便使用XMLHttpRequest发送

  • 异步上传二进制文件

为什么要模拟表单

传统的传递参数可以通过form表单,设置action参数,点击submit触发提交

<form action="xxxx" method="get" class="form-example">
    <input type="text" name="name" id="name" required>
    <input type="submit" value="Subscribe!">
</form>

这种提交参数的方式有个缺陷,就是提交后每次页面会刷新,这样体验不好,还重复加载页面,影响服务器性能,后来有了Ajax,通过XMLHttpRequest异步传输数据,实现异步加载功能。而此时FormData可以作为参数的一种结构类型,并且结构和form一致,对于服务器端来说,收到的请求参数都像是表单上触发submit一样的

var formData = new FormData();
var request = new XMLHttpRequest();
request.open("POST", "http://foo.com/submitform.php");
request.send(formData);

Ajax一定需要使用FormData吗

答案是否定的,可以Ajax不使用FormData

通过前文,我们知道Ajax技术可以替换直接使用表单的用法,然而,表单的提交方式很多,具体来说有四种:

  • 使用POST方法并将enctype属性设置为application / x-www-form-urlencoded(默认);

    Content-Type: application/x-www-form-urlencoded
    
    foo=bar&baz=The+first+line.%0D%0AThe+second+line.%0D%0A
    
  • 使用POST方法并将enctype属性设置为text / plain

    Content-Type: text/plain
    
    foo=bar
    baz=The first line.
    The second line.
    
  • 使用POST方法并将enctype属性设置为multipart / form-data

    Content-Type: multipart/form-data; boundary=---------------------------314911788813839
    
    -----------------------------314911788813839
    Content-Disposition: form-data; name="foo"
    
    bar
    -----------------------------314911788813839
    Content-Disposition: form-data; name="baz"
    
    The first line.
    The second line.
    
    -----------------------------314911788813839--
    
  • 使用GET方法(在这种情况下,enctype属性将被忽略)。

?foo=bar&baz=The%20first%20line.%0AThe%20second%20line.

简单来说,就是表单的Content-Type值会不同,通过表单的method 、enctype等参数决定,而纯Ajax提交表单时,需要手动设置Content-Type值,通过FormDate,可以自动填充

XMLHttpRequest的实例可以通过两种方式用于提交表单:

  • 仅使用AJAX
    仅使用AJAX更复杂,但通常更灵活,更强大。

    手动设置参数:

     /* method is POST */
          oAjaxReq.open("post", oData.receiver, true);
          if (oData.technique === 3) {
            /* enctype is multipart/form-data */
            var sBoundary = "---------------------------" + Date.now().toString(16);
            oAjaxReq.setRequestHeader("Content-Type", "multipart\/form-data; boundary=" + sBoundary);
            oAjaxReq.sendAsBinary("--" + sBoundary + "\r\n" +
                oData.segments.join("--" + sBoundary + "\r\n") + "--" + sBoundary + "--\r\n");
          }
    
  • 使用FormData API
    使用FormData API是最简单,最快的方法,但是具有无法对收集的数据进行字符串化的缺点

FormData对象的创建

更多详细

像创建对象一样来创建

你可以创建一个空的FormData对象,并通过append()方法添加参数

var formData = new FormData();

formData.append("username", "Groucho");
formData.append("accountnum", 123456); // 数字 123456 立即被转化为字符串 "123456"

// HTML file 组件
formData.append("userfile", fileInputElement.files[0]); //fileInputElement对象获取方式 $("#fileID").get(0)


// blob
var content = '<a id="a"><b id="b">hey!</b></a>'; // 构建文件的body
var blob = new Blob([content], { type: "text/xml"});

formData.append("webmasterfile", blob);

var request = new XMLHttpRequest();
request.open("POST", "http://foo.com/submitform.php");
request.send(formData);

注意:append()方法接收file,blob,string,因此当非file和blob时,自动转为string

PS:关于blob对象,只要记住它和file对象在使用上差不多就行了,和file对象唯一的不同就是file对象多了个名字,并且file对象的基础就是blob对象,所以两者在使用上没有什么区别。

通过已有的Form来创建

语法
var formData = new FormData(someFormElement);
例子
var formElement = document.querySelector("form");  //表单对象
var request = new XMLHttpRequest();
request.open("POST", "submitform.php");
request.send(new FormData(formElement));  //获取formData对象,并发送

从表单获取参数后,也可以添加额外参数进去

var formElement = document.querySelector("form");  //表单对象
var formData = new FormData(formElement); //获取formData对象
var request = new XMLHttpRequest();
request.open("POST", "submitform.php");
formData.append("serialnumber", serialNumber++);  //添加额外参数
request.send(formData);

上传文件

<form>表单中含有file类型的input

<form enctype="multipart/form-data" method="post" name="fileinfo">
  <label>Your email address:</label>
  <input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /><br />
  <label>Custom file label:</label>
  <input type="text" name="filelabel" size="12" maxlength="32" /><br />
  <label>File to stash:</label>
  <input type="file" name="file" required />
  <input type="submit" value="Stash the file!" />
</form>
<div></div>

你可以使用下面的代码发送上述表单

var form = document.forms.namedItem("fileinfo");
form.addEventListener('submit', function(ev) {

  var oOutput = document.querySelector("div"),
      oData = new FormData(form);  //直接利用表单构建包含file的FormData

  oData.append("CustomField", "This is some extra data");

  var oReq = new XMLHttpRequest();
  oReq.open("POST", "stash.php", true);
  oReq.onload = function(oEvent) {
    if (oReq.status == 200) {
      oOutput.innerHTML = "Uploaded!";
    } else {
      oOutput.innerHTML = "Error " + oReq.status + " occurred when trying to upload your file.<br \/>";
    }
  };

  oReq.send(oData);
  ev.preventDefault();
}, false);

您还可以将File或Blob直接附加到FormData对象,如下所示:

data.append("myfile", myBlob, "filename.txt");

使用append()方法时,可以使用第三个可选参数在要发送到服务器的Content-Disposition标头中传递文件名。 如果未指定文件名(或不支持该参数),则使用名称“ blob”。

常用方法

append

语法
formData.append(name, value);
formData.append(name, value, filename);
  • name
    value中包含的数据对应的表单名称。
  • value
    表单的值。可以是USVString 或 Blob (包括子类型,如 File)。
  • filename 可选
    传给服务器的文件名称 (一个 USVString), 当一个 Blob 或 File 被作为第二个参数的时候, Blob 对象的默认文件名是 “blob”。 File 对象的默认文件名是该文件的名称
示例
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');

这项技术使得多文件上传的处理更加简单,因为所得数据结构更有利于循环。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值