使用FormData对象

  • 版本网址缩略名: DOM/XMLHttpRequest/FormData/Using_FormData_Objects
  • 版本标题: Using FormData Objects
  • 版本 id: 235716
  • 创建于:
  • 创建者: ziyunfei
  • 是否是当前版本?
  • 评论 page created, 758 words added

修订内容

The FormData object lets you compile a set of key/value pairs to send using XMLHttpRequest. Its primarily intended for use in sending form data, but can be used independently from forms in order to transmit keyed data. The transmitted data is in the same format that the form's submit() method would use to send the data if the form's encoding type were set to "multipart/form-data".

Creating a FormData object from scratch

You can build a FormData object yourself, instantiating it then appending fields to it by calling its append() method, like this:

var oMyForm = new FormData();

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

// HTML file input user's choice...
oMyForm.append("userfile", fileInputElement.files[0]);

// JavScript file-like object...
/*
* In the future...:
* var oBlob = new BlobBuilder();
* ...but for now...:
*/
var oBlob = new MozBlobBuilder();

oBlob.append("<a id=\"a\"><b id=\"b\">hey!<\/b><\/a>"); // the body of the new file...

oMyForm.append("webmasterfile", oBlob.getBlob("text\/xml"));

var oReq = new XMLHttpRequest();
oReq.open("POST", "http://foo.com/submitform.php");
oReq.send(oMyForm);
Note: The fields "userfile" and "webmasterfile" contain both 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 {{ domxref("Blob") }}, {{ domxref("File") }}, or a string: if neither, the value is converted to a string).

This example builds a FormData instance containing values for fields named "username", "accountnum", "userfile" and "webmasterfile", then uses the XMLHttpRequest method send() to send the form's data. The field "webmasterfile" is a Blob. A Blob object represents a file-like object of immutable, raw data. Blobs represent data that isn't necessarily in a JavaScript-native format. The {{ domxref("File") }} interface is based on Blob, inheriting blob functionality and expanding it to support files on the user's system. In order to build a Blob you can use the getBlob() method of each BlobBuilder instance or invoke the Blob constructor directly.

Retrieving a FormData object from an HTML form

To construct a FormData object that contains the data from an existing {{ HTMLElement("form") }}, specify that form element when creating the FormData object:

var newFormData = new FormData(someFormElement);

For example:

var formElement = document.getElementById("myFormElement");
var oReq = new XMLHttpRequest();
oReq.open("POST", "submitform.php");
oReq.send(new FormData(formElement));

You can also append additional data to the FormData object between retrieving it from a form and sending it, like this:

var formElement = document.getElementById("myFormElement");
formData = new FormData(formElement);
formData.append("serialnumber", serialNumber++);
oReq.send(formData);

This lets you augment the form's data before sending it along, to include additional information that's not necessarily user editable on the form.

Sending files using a FormData object

You can also send files using FormData. Simply include an {{ HTMLElement("input") }} element of type "file":

<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 />
</form>
<div id="output"></div>
<a href="javascript:sendForm()">Stash the file!</a>

Then you can send it using code like the following:

function sendForm() {
  var oOutput = document.getElementById("output");
  var oData = new FormData(document.forms.namedItem("fileinfo"));

  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 uploading your file.<br \/>";
    }
  };

  oReq.send(oData);
}

Note that this example is directing the output to a Perl CGI script running on the server, and handles HTTP errors, although not prettily.

You can also append a {{ domxref("File") }} or {{ domxref("Blob") }} directly to the {{ domxref("XMLHttpRequest/FormData", "FormData") }} object, like this:

data.append("myfile", myBlob);

When using a {{ domxref("Blob") }}, the filename reported to the server in the HTTP "Content-Disposition" header is browser-specific; Firefox uses simply "blob," while Chrome uses a random string, for example.

You can also use FormData with jQuery if you set the right options:

var fd = new FormData(document.getElementById("fileinfo"));
fd.append("CustomField", "This is some extra data");
$.ajax({
  url: "stash.php",
  type: "POST",
  data: fd,
  processData: false,  // tell jQuery not to process the data
  contentType: false   // tell jQuery not to set contentType
});

 

{{ languages( {"en": "en/DOM/XMLHttpRequest/FormData/Using_FormData_Objects" } ) }}

修订版来源

<p>The <a href="/zh-cn/DOM/XMLHttpRequest/FormData" title="zh-cn/DOM/XMLHttpRequest/FormData"><code>FormData</code></a> object lets you compile a set of key/value pairs to send using <code>XMLHttpRequest</code>. Its primarily intended for use in sending form data, but can be used independently from forms in order to transmit keyed data. The transmitted data is in the same format that the form's <code>submit()</code> method would use to send the data if the form's encoding type were set to "multipart/form-data".</p>
<h2>Creating a FormData object from scratch</h2>
<p>You can build a <code>FormData</code> object yourself, instantiating it then appending fields to it by calling its <a href="/zh-cn/DOM/XMLHttpRequest/FormData#append()" title="zh-cn/XMLHttpRequest/FormData#append()"><code>append()</code></a> method, like this:</p>
<pre class="deki-transform">var oMyForm = new FormData();

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

// HTML file input user's choice...
oMyForm.append("userfile", fileInputElement.files[0]);

// JavScript file-like object...
/*
* In the future...:
* var oBlob = new BlobBuilder();
* ...but for now...:
*/
var oBlob = new MozBlobBuilder();

oBlob.append("&lt;a id=\"a\"&gt;&lt;b id=\"b\"&gt;hey!&lt;\/b&gt;&lt;\/a&gt;"); // the body of the new file...

oMyForm.append("webmasterfile", oBlob.getBlob("text\/xml"));

var oReq = new XMLHttpRequest();
oReq.open("POST", "http://foo.com/submitform.php");
oReq.send(oMyForm);
</pre>
<div class="note"><strong>Note:</strong> The fields "userfile" and "webmasterfile" contain both a file. The number assigned to the field "accountnum" is immediately converted into a string by the <a href="/zh-cn/DOM/XMLHttpRequest/FormData#append()" title="zh-cn/XMLHttpRequest/FormData#append()"><code>FormData.append()</code></a> method (the field's value can be a {{ domxref("Blob") }}, {{ domxref("File") }}, or a string: <strong>if neither, the value is converted to a string</strong>).</div>
<p>This example builds a <code>FormData</code> instance containing values for fields named "username", "accountnum", "userfile" and "webmasterfile", then uses the <code>XMLHttpRequest</code> method <a href="/zh-cn/DOM/XMLHttpRequest#send()" title="zh-cn/XMLHttpRequest#send()"><code>send()</code></a> to send the form's data. The field "webmasterfile" is a <a href="/zh-cn/DOM/Blob" title="zh-cn/DOM/Blob"><code>Blob</code></a>. A <a href="/zh-cn/DOM/Blob" title="zh-cn/DOM/Blob"><code>Blob</code></a> object represents a file-like object of immutable, raw data. Blobs represent data that isn't necessarily in a JavaScript-native format. The {{ domxref("File") }} interface is based on <a href="/zh-cn/DOM/Blob" title="zh-cn/DOM/Blob"><code>Blob</code></a>, inheriting blob functionality and expanding it to support files on the user's system. In order to build a <a href="/zh-cn/DOM/Blob" title="zh-cn/DOM/Blob"><code>Blob</code></a> you can use the <a href="/zh-cn/DOM/BlobBuilder#getBlob()" title="zh-cn/DOM/BlobBuilder#getBlob()"><code>getBlob()</code></a> method of each <a href="/zh-cn/DOM/BlobBuilder" title="zh-cn/DOM/BlobBuilder"><code>BlobBuilder</code></a> instance or <strong>invoke the <a href="/zh-cn/DOM/Blob#Constructor" title="zh-cn/DOM/Blob#Constructor"><code>Blob</code> constructor</a> directly</strong>.</p>
<h2>Retrieving a FormData object from an HTML form</h2>
<p>To construct a <code>FormData</code> object that contains the data from an existing {{ HTMLElement("form") }}, specify that form element when creating the <code>FormData</code> object:</p>
<pre>var newFormData = new FormData(someFormElement);
</pre>
<p>For example:</p>
<pre class="deki-transform">var formElement = document.getElementById("myFormElement");
var oReq = new XMLHttpRequest();
oReq.open("POST", "submitform.php");
oReq.send(new FormData(formElement));
</pre>
<p>You can also append additional data to the <code>FormData</code> object between retrieving it from a form and sending it, like this:</p>
<pre class="deki-transform">var formElement = document.getElementById("myFormElement");
formData = new FormData(formElement);
formData.append("serialnumber", serialNumber++);
oReq.send(formData);</pre>
<p>This lets you augment the form's data before sending it along, to include additional information that's not necessarily user editable on the form.</p>
<h2>Sending files using a FormData object</h2>
<p>You can also send files using <code>FormData</code>. Simply include an {{ HTMLElement("input") }} element of type "file":</p>
<pre class="deki-transform">&lt;form enctype="multipart/form-data" method="post" name="fileinfo"&gt;
  &lt;label&gt;Your email address:&lt;/label&gt;
  &lt;input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /&gt;&lt;br /&gt;
  &lt;label&gt;Custom file label:&lt;/label&gt;
  &lt;input type="text" name="filelabel" size="12" maxlength="32" /&gt;&lt;br /&gt;
  &lt;label&gt;File to stash:&lt;/label&gt;
  &lt;input type="file" name="file" required /&gt;
&lt;/form&gt;
&lt;div id="output"&gt;&lt;/div&gt;
&lt;a href="javascript:sendForm()"&gt;Stash the file!&lt;/a&gt;
</pre>
<p>Then you can send it using code like the following:</p>
<pre class="deki-transform">function sendForm() {
  var oOutput = document.getElementById("output");
  var oData = new FormData(document.forms.namedItem("fileinfo"));

  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 uploading your file.&lt;br \/&gt;";
    }
  };

  oReq.send(oData);
}
</pre>
<p>Note that this example is directing the output to a Perl CGI script running on the server, and handles HTTP errors, although not prettily.</p>
<p>You can also append a {{ domxref("File") }} or {{ domxref("Blob") }} directly to the {{ domxref("XMLHttpRequest/FormData", "FormData") }} object, like this:</p>
<pre>data.append("myfile", myBlob);
</pre>
<p>When using a {{ domxref("Blob") }}, the filename reported to the server in the HTTP "Content-Disposition" header is browser-specific; Firefox uses simply "blob," while Chrome uses a random string, for example.</p>
<p>You can also use <code>FormData</code> with jQuery if you set the right options:</p>
<pre class="deki-transform">var fd = new FormData(document.getElementById("fileinfo"));
fd.append("CustomField", "This is some extra data");
$.ajax({
  url: "stash.php",
  type: "POST",
  data: fd,
  processData: false,  // tell jQuery not to process the data
  contentType: false   // tell jQuery not to set contentType
});
</pre>
<p> </p>
<p>{{ languages( {"en": "en/DOM/XMLHttpRequest/FormData/Using_FormData_Objects" } ) }}</p>
恢复到这个版本