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:

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

About Paul Rouget

Paul is a Firefox developer.

More articles by Paul Rouget…


21 comments

  1. marcoos

    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/ :)

    May 17th, 2010 at 13:44

    1. Paul Rouget

      Yes, exactly.

      May 18th, 2010 at 05:32

  2. Edwin Martin

    Will there also be an setFormData()?

    May 17th, 2010 at 15:31

  3. Brett Zamir

    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?

    May 17th, 2010 at 21:38

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

    May 18th, 2010 at 01:02

  5. QOAL

    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?

    May 18th, 2010 at 03:06

  6. fpiat

    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

    May 18th, 2010 at 04:02

    1. Paul Rouget

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

      May 18th, 2010 at 06:39

  7. pd

    Is this going to be included in IE9?

    May 18th, 2010 at 10:36

    1. Andy

      Ask for it in the IE Blog and it might…

      June 21st, 2010 at 15:53

  8. […] 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 = […]

    June 23rd, 2010 at 08:46

  9. AlfonsoML

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

    July 1st, 2010 at 02:04

  10. […] – 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 […]

    July 6th, 2010 at 22:51

  11. […] 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: […]

    July 7th, 2010 at 18:58

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

    July 11th, 2010 at 20:30

  13. kn33ch41

    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!

    July 18th, 2010 at 17:49

  14. kn33ch41

    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?

    July 18th, 2010 at 19:27

  15. Daniel Kirsch

    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.

    September 21st, 2010 at 16:01

  16. Glenn Maynard

    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.

    December 17th, 2010 at 16:00

  17. André

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

    November 25th, 2012 at 15:23

    1. Robert Nyman

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

      November 26th, 2012 at 01:28

Comments are closed for this article.