FormData

The FormData interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method. It uses the same format a form would use if the encoding type were set to "multipart/form-data".

You can also pass it directly to the URLSearchParams constructor if you want to generate query parameters in the way a

would do if it were using simple GET submission.

An object implementing FormData can directly be used in a for...of structure, instead of entries(): for (var p of myFormData) is equivalent to for (var p of myFormData.entries()).

This feature is available in Web Workers.

使用 FormData api 虽然是最简单和最快速的上传表单和文件的方法,但它的缺点也很明显,就是它不能被字符串化。

不使用FormData api 的情况下,可以通过使用FileReader api来使用ajax上传。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# constructor
FormData()

# Methods
FormData.append()
# Appends a new value onto an existing key inside a FormData object, or adds the key if it does not already exist.

FormData.delete()
# Deletes a key/value pair from a FormData object.

FormData.entries()
# Returns an iterator allowing to go through all key/value pairs contained in this object.

FormData.get()
# Returns the first value associated with a given key from within a FormData object.

FormData.getAll()
# Returns an array of all the values associated with a given key from within a FormData.

FormData.has()
# Returns a boolean stating whether a FormData object contains a certain key.

FormData.keys()
# Returns an iterator allowing to go through all keys of the key/value pairs contained in this object.

FormData.set()
# Sets a new value for an existing key inside a FormData object, or adds the key/value if it does not already exist.

FormData.values()
# Returns an iterator allowing to go through all values contained in this object.

Creating a FormData object from scratch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Note: The fields "userfile" and "webmasterfile" both contain a file. The number assigned to the field "accountnum" is immediately converted into a string by the FormData.append() method (the field's value can be a Blob, File, or a string: if the value is neither a Blob nor a File, the value is converted to a string).

var formData = new FormData();

formData.append("username", "Groucho");
formData.append("accountnum", 123456); // number 123456 is immediately converted to a string "123456"

// HTML file input, chosen by user
formData.append("userfile", fileInputElement.files[0]);

// JavaScript file-like object
var content = '<a id="a"><b id="b">hey!</b></a>'; // the body of the new file...
var blob = new Blob([content], { type: "text/xml"});

formData.append("webmasterfile", blob);
// formData.append("webmasterfile", blob, "filename.txt");
// When no filename is specified (or the parameter isn't supported), the name "blob" is used.

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

Retrieving a FormData object from an HTML form

1
2
3
4
5
6
7
8
9
10
# FormData will only use input fields that use the name attribute.

var formData = new FormData(someFormElement);

var formElement = document.querySelector("form");
var formData = new FormData(formElement);
var request = new XMLHttpRequest();
request.open("POST", "submitform.php");
formData.append("serialnumber", serialNumber++);
request.send(formData);

Sending files using a FormData object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<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);

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);

Using a formdata event

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const formElem = document.querySelector('form');

formElem.addEventListener('submit', (e) => {
// on form submission, prevent default
e.preventDefault();

// construct a FormData object, which fires the formdata event
new FormData(formElem);
});

# Note: The formdata event and FormDataEvent object are available in Chrome from version 77 (and other equivalent Chromiums), and Firefox 72 (first available behind the dom.formdata.event.enabled pref in Firefox 71).
formElem.addEventListener('formdata', (e) => {
console.log('formdata fired');

// Get the form data from the event object
let data = e.formData;
for (var value of data.values()) {
console.log(value);
}

// submit the data via XHR
let request = new XMLHttpRequest();
request.open("POST", "/formHandler");
request.send(data);
});
1
2
3
4
5
6
7
8
9
10
// jquery use FormData
var fd = new FormData(document.querySelector("form"));
fd.append("CustomField", "This is some extra data");
$.ajax({
url: "stash.php",
type: "POST",
data: fd,
processData: false, // 不处理数据
contentType: false // 不设置内容类型
});
Reference
  1. https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects