为了通过XHR传输与表单格式相同的数据,既表单数据序列化,以前需要手动序列化(高程三-14.4表单序列化)
XMLHttpRequest 2级定义了FormData类型,这样就原生支持创建表单格式数据。
用法参考

1 基本用法

[FormData](https://developer.mozilla.org/en/DOM/XMLHttpRequest/FormData#append()) 对象的字段类型可以是 Blob, File, 或者 string: 如果它的字段类型不是Blob也不是File,则会被转换成字符串类

  1. var formData = new FormData();
  2. formData.append("username", "Groucho");
  3. formData.append("accountnum", 123456); //数字123456会被立即转换成字符串 "123456"
  4. // HTML 文件类型input,由用户选择
  5. formData.append("userfile", fileInputElement.files[0]);
  6. // JavaScript file-like 对象
  7. var content = '<a id="a"><b id="b">hey!</b></a>'; // 新文件的正文...
  8. var blob = new Blob([content], { type: "text/xml"});
  9. formData.append("webmasterfile", blob);
  10. var request = new XMLHttpRequest();
  11. request.open("POST", "http://foo.com/submitform.php");
  12. request.send(formData);

2 配合表单元素

同时构造函数还可以传入表单元素,也可以借此借助表单元素预先向其中填入键值对。

  1. // FormData将仅使用具有name属性的输入字段。
  2. var formElement = document.querySelector("form");
  3. var formData = new FormData(formElement);
  4. var request = new XMLHttpRequest();
  5. request.open("POST", "submitform.php");
  6. 还可以在创建一个包含Form表单数据的FormData对象之后和发送请求之前,附加额外的数据到FormData对象里,
  7. 如下,这样你就可以在发送请求之前自由地附加不一定是用户编辑的字段到表单数据里
  8. formData.append("serialnumber", serialNumber++);
  9. request.send(formData);

3 无需显式设置请求头部

xhr对象能够识别传入的数据类型是FormData实例,并配置对应请求头部信息
$.ajax

  1. var fd = new FormData(document.querySelector("form"));
  2. fd.append("CustomField", "This is some extra data");
  3. $.ajax({
  4. url: "stash.php",
  5. type: "POST",
  6. data: fd,
  7. processData: false, // 不处理数据
  8. contentType: false // 不设置内容类型
  9. });

axiose
image.png

4 数组

image.png

5 项目记录

5.1 文件dataUrl转换成blob

一次某个项目,有个表单创建和编辑的页面,需要上传图片,编辑时候,后端接口返回的是图片的dataUrl(base64),提交时候还需要转换成file/blob类型,否则图片信息就丢失

  1. let dataURIToBlob = (dataURI) => {
  2. const splitDataURI = dataURI.split(',')
  3. const byteString = splitDataURI[0].indexOf('base64') >= 0 ? atob(splitDataURI[1]) : decodeURI(splitDataURI[1])
  4. const mimeString = splitDataURI[0].split(':')[1].split(';')[0]
  5. const ia = new Uint8Array(byteString.length)
  6. for (let i = 0; i < byteString.length; i++)
  7. ia[i] = byteString.charCodeAt(i)
  8. return new Blob([ia], { type: mimeString })
  9. }

image.png