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.
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.
Post filed under: html5, javascript.
Any word on how this will play with Safari? I’m working on a site that only need to support FF and Safari and this could be a great addition.
Luke, January 23rd, 2010Not sure when they will implement the File API, but there has been a bug filed on webkits bug tracking site requesting they add it.
The Css Ninja, January 23rd, 2010Nice work!
surreydude, February 5th, 2010Tested the demo to work in the release version of Firefox 3.6. Very cool. I noticed after the image is “uploaded” it outputs the image as a base64 encoded data URI… any reason you’re doing this instead of storing the image on the server?
I assume it is possible to simply store the image on the server if desired.
Michael Butler, February 6th, 2010@Michael – It’s actually encoded into a base64 string before it uploads (using the File API). That way I can display the image to the user before any uploading happens. If you disable your network connection and drag in the images it will still display them but will obviously fail on trying to upload them to the server.
The Css Ninja, February 6th, 2010That makes sense! I can see how easy it is then to use the offline data API to store the images locally and upload them later on. Can’t wait to try this out.
Michael, February 6th, 2010When I try the demo in FF3.6 on Ubuntu, Firefox tries to open the dropepd document, instead of uploading them. It seems to ignore the File and Drag And Drop APIs.
Émile Jetzer, February 28th, 2010@Émile – That’s not good, I don’t have a linux machine available for me to test on so I can’t see what’s happening. Can you try my font dragr web app (it uses the file API too) in FF3.6 on your linux machine and let me know if you have the same issue?
The Css Ninja, March 1st, 2010The font dragr doesn’t work either. It seems to be exactly the same issue.
Émile Jetzer, March 1st, 2010@Émile – So I asked around for a few people with linux to try my demo and it’s working for them, but someone did mention that having the Jetpack add-on installed kills the drag and drop functionality but only on linux machines, mac/windows are OK. It’s been filed in the issue tracker so they’re aware of it.
The Css Ninja, March 2nd, 2010I disabled Jetpack, and now it works all right! Thank you!
Émile Jetzer, March 6th, 2010