Mozilla

Firefox 4: easier JS form handling with FormData

This feature has landed in Mozilla Central (trunk) and only available with a Firefox Nightly Build for the time being.

XMLHttpRequest Level 2 (editor’s draft) adds support for the new FormData interface. FormData objects provide 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 in “multipart/form-data” format.

Why FormData?

When you want to send complex data to a server from a web page (files, non-ASCII content), you must use the multipart/form-data content type. To set the content type in a <form>, you write:

<form method="post" enctype="multipart/form-data" action="http://foo.bar/upload.php">
<input type="file" name="media"/>
<input name="nickname"/>
<input name="website"/>
<input type="submit" value="upload"/>
</form>

This is what you usually do to upload a file.

Starting with Firefox 3.6, you can manipulate files with JavaScript (see File API), and maybe you want to send files using XMLHttpRequest. But if, for example, you want to reproduce this form, it’s really hard because you’ll have to create the multipart/form-data content yourself in JavaScript (see, for example, this code I wrote a while ago implementing a multipart/form-data: ugly and slow).

This is where FormData is useful: to reproduce the <form> submission mechanism in JavaScript

The FormData object

The FormData object lets you compile a set of key/value pairs to send using XMLHttpRequest. This object has only one method:

append(key, value);

where key is the name of your value, and where value can be a string or a file.

You can create a FormData object, append values and then send it through XMLHttpRequest. If you want to simulate the previous form, you write:

// aFile could be from an input type="file" or from a Dragged'n Dropped file
var formdata = new FormData();
formdata.append("nickname", "Foooobar");
formdata.append("website", "http://hacks.mozilla.org");
formdata.append("media", aFile);
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://foo.bar/upload.php");
xhr.send(formdata);

FormData and the <form> element

Firefox extends the HTML form element slightly, adding a getFormData() method that lets you fetch a form’s data as a FormData object. This is not yet part of the HTML standard, but is expected to be added to the specification at some point in the future (although possibly with a different name):

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

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

var formElement = document.getElementById("myFormElement");
formData = formElement.getFormData();
formData.append("serialnumber", serialNumber++);
xhr.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.

Resources

21 comments

Comments are now closed.

  1. marcoos wrote on May 17th, 2010 at 13:44:

    So, if I’m getting this right, it means that with FormData and all the file-related stuff implemented in Gecko recently we can finally implement a JS progress bar for uploads without doing any weird sendAsBinary() stuff, and use the same backend code that would be used for the plain HTML forms.

    Basically, this makes nasty Flash hacks like SWFUpload not needed anymore, hurrah!

    BTW, here’s the Polish translation of this post: http://blog.marcoos.com/2010/05/17/mozilla-hacks-interfejs-formdata-wkrotce-w-firefoksie/ :)

    1. Paul Rouget wrote on May 18th, 2010 at 05:32:

      Yes, exactly.

  2. Edwin Martin wrote on May 17th, 2010 at 15:31:

    Will there also be an setFormData()?

  3. Brett Zamir wrote on May 17th, 2010 at 21:38:

    There seems to be no problem in sending Unicode UTF-8 data (i.e., non-ASCII content) without enctype=”multipart/form-data” as long as the file is in UTF-8. Am I misunderstanding?

  4. Pingback from Firefox 4: FormData를 사용하여 JS로 보다 쉽게 폼 다루기 ✩ Mozilla 웹 기술 블로그 on May 18th, 2010 at 01:02:

    […] 원본: http://hacks.mozilla.org/2010/05/formdata-interface-coming-to-firefox/ […]

  5. QOAL wrote on May 18th, 2010 at 03:06:

    Is it possible to remove or amend data?
    Either by something like formData.append(key, null); or another way?
    I ask because there must be some situation where you’d do formData = formElement.getFormData(); but want to amend the form data after?

  6. fpiat wrote on May 18th, 2010 at 04:02:

    Anybody who make development have already implement this. What we need is the the section 4.10 Forms from the html5 specs. But canvas seems to be more sexy. sighhhh

    1. Paul Rouget wrote on May 18th, 2010 at 06:39:

      We are working on it: https://wiki.mozilla.org/User:Mounir.lamouri/HTML5_Forms

  7. pd wrote on May 18th, 2010 at 10:36:

    Is this going to be included in IE9?

    1. Andy wrote on June 21st, 2010 at 15:53:

      Ask for it in the IE Blog and it might…

  8. Pingback from HTML5 adoption stories: box.net and html5 drag and drop ✩ Mozilla Hacks – the Web developer blog on June 23rd, 2010 at 08:46:

    […] and we don’t need special file size restrictions. In the future, we’ll consider using yet another way to efficiently upload files that is supported in Firefox 4 and uses the traditional …: var files = event.originalEvent.dataTransfer.files; // drop event var url = […]

  9. AlfonsoML wrote on July 1st, 2010 at 02:04:

    IE9 won’t support it: http://alfonsoml.blogspot.com/2010/07/formdata-interface-wont-be-available.html

  10. Pingback from Firefox 4 beta 1 is here – what’s in it for web developers? ✩ Mozilla Hacks – the Web developer blog on July 6th, 2010 at 22:51:

    […] – We also have support for the FormData method, which makes it much easier to send complex data from the File API and other sources to […]

  11. Pingback from Firefox 4 – FormData and the new File.url object ✩ Mozilla Hacks – the Web developer blog on July 7th, 2010 at 18:58:

    […] from Jonas Sicking, who does much of the work inside of Gecko on content facing features. He covers FormData, which we’ve talked about before, but shows how it can connect to an important part of the File API we’ve added for Firefox 4: […]

  12. Pingback from Firefox 4 – FormData and the new File.url object ✩ Mozilla 웹 기술 블로그 on July 11th, 2010 at 20:30:

    […] 관련 기능에 많은 작업을 하고 있는 조나스 시킹의 객원 글입니다. 그는 우리가 이전에 얘기했던 FormData에 대해서 다루기는 하지만, 거기에 더하여 Firefox 4에 추가된 File API의 […]

  13. kn33ch41 wrote on July 18th, 2010 at 17:49:

    I’m very much looking forward to using this method for asynchronous file uploads. The current methods in use to guarantee that the server reads data as standard posts are not too pleasant.

    I hope the rumours are true and Firefox 4 gets released this November!

  14. kn33ch41 wrote on July 18th, 2010 at 19:27:

    While developing an asynchronous file uploader script it occurred to me that it also abides by the same-domain restriction. However, a form can be posted anywhere, and it’s a pretty common requirement. For example, posting images to a designated image processing server. Is there going to be some exception for XHR 2 to handle sending data to alternate domains/subdomains?

  15. Daniel Kirsch wrote on September 21st, 2010 at 16:01:

    I like the new form possibilities. However as long as I need to support browsers that don’t support it, its usually easier to simply have one version and do it the traditional way.
    I also like the new xhr.upload (nsIXMLHttpRequestUpload) object which lets me add a progress indicator for my upload.
    So it would help a lot if I could have something similar to the xhr.upload object for the FORM element. This way, I could add a progress indicator to my application without the need to create a XMLHTTPRequest to send the data.
    The most easiest way would be to simply add an “onprogress” listener to the FORM element either by attribute or addEventListener:

    Well, this is probably not possible because the server might already send something back to the client to display, but maybe there is a way.

  16. Glenn Maynard wrote on December 17th, 2010 at 16:00:

    In case anyone else is wondering where this went, it’s now “new FormData(formElement)”, though this still doesn’t seem to have made it into any specs or docs. Chrome supports it this way, too.

    The old way was better: any JavaScript object could implement a getFormData method to return a FormData for the object. If I have my own object that can generate a FormData of its contents, it could expose a getFormData method, providing an interface consistent and compatible with HTMLFormElement. As a special-case FormData constructor, that natural consistency is lost.

  17. André wrote on November 25th, 2012 at 15:23:

    Please, tell me, can I send data from a img tag src instead of take the files from input ??

    1. Robert Nyman wrote on November 26th, 2012 at 01:28:

      No, to send data it needs to be through a form.

Comments are closed for this article.