The File API has changed

Recently I have been touting how awesome and revolutionary the File API is through a few demo’s. After some feedback on webapps mailing list there have been some major changes to the API and how it works.

I have updated my previous drag and drop upload demo to reflect the API changes, as of Firefox 3.6b3 the API supports both the original API and the updated one. The older model will eventually be dropped, it’s only in there for legacy purposes. To use the demo you will need Firefox 3.6 installed. You can also watch the screencast of it in action.

The biggest change is with the file handling, it is now processed asynchronously with progress events so we can attach listeners. The advantage of this is if a user drags in many files or a large file the UI won’t be locked up while it’s processing the data, much like XmlHttpRequest works.

The File object

The File object has been updated to reflect the new specs changes and has deprecated all the previous methods we used to get the file in various formats e.g. getAsDataUrl(), getAsText(), getAsBinary(). We now handle these methods in the new FileReader object.

It has also renamed the 2 properties for accessing the files name and size from fileName/fileSize to name/size respectively.

The FileReader object

This new object allows us to asynchronously read the contents of a file from a drop event.

var reader = new FileReader();

reader.addEventListener("loadend", TCNDDU.buildImageListItem, false);
reader.readAsDataURL(file);

Instead of locking the UI while we wait for it to loop through all the dropped files and then convert them to a DataUrl. The FileReader does this asynchronously. We attach to the onloadend event handler which will fire once the current file has been read into the result attribute. Upon the event firing we then take the event result and add the DataURL to the source of the image to be displayed to the user while it uploads.

Send the binary data

Once we have the file we send it to be processed for an XHR call so we can upload it to the server. Same as above we need to create a file reader and attach to the onloadend event which we then pass to the sendAsBinary() method.

var getBinaryDataReader = new FileReader();

getBinaryDataReader.addEventListener("loadend", function(evt){xhr.sendAsBinary(evt.target.result);}, false);
getBinaryDataReader.readAsBinaryString(file);

Similar code we used for the image display handling, but we use the readAsBinaryString() method to return the files binary data for uploading.

Further reading

As the 3.6 final release date is coming closer Mozilla has been ramping up demos and documentation about the File API. Some good documentation on handling files in web applications.

Update: Mika Tuupola has a good article on handling the server side (PHP) part of file uploading.

The hacks blog has recently put up some great information about the File API along with an excellent demo extracting EXIF data from an image.

Now we just need webkit to push out the File API to their nightly builds.