Using the File API for reading file information & multiple file uploads – another sister specification to HTML5

A constant drag when developing web sites have been when the end user wants to upload files to it. Luckily, though, those problems are to come to an end due to the File API.

What is it?

The File API is there to describe how interactions with files are handled, for reading information about them and their data as well, to be able to upload it.

There are two ways you can detect the files a user is trying to upload:

  • Through an <input type="file"> element and its onchange event.
  • By drag and drop you can use the ondrop event to detect which file(s) were dropped.

Code sample

Let’s take a look at an easy sample. First, for the onhange event for the <input type="file"> element, that element has a specific files property you can check:

	
	<input id="files-upload" type="file" multiple>
	var filesUpload = document.getElementById("files-upload");
	filesUpload.onchange = function () {
		// Access to data about all files
		var files = this.files;
	};

Similarily, for the ondrop event handler on virtually any element, you can check for file data in the event.dataTransfer property:

	<p id="drop-area">
		Drag and drop files here
	</p>
	var dropArea = document.getElementById("drop-area");
	
	// Needed for web browser compatibility
	dropArea.ondragenter = function () {
		return false;
	};
	
	// Needed for web browser compatibility
	dropArea.ondragover = function () {
		return false;
	};
	
	dropArea.ondrop = function (evt) {
		var files = evt.dataTransfer.files;
		return false;
	};

So, when we have a reference to the files to work with, we can iterate over them and read out their data:

	for (var i=0, il=files.length; i<il; i++) {
		file.name; // Get the name of the file
		file.size; // Get the size of the file, in bytes
		file.type; // Get the type of the file
	};

In my tests, the type of the file seems fairly consistent, but for Photoshop files, Firefox and Google Chrome reported different types (although both with Photoshop in their value :-) ).

Demo

I have put together a demo of the File API in action, as a part of my HTML5 – Information and samples for HTML5 and related APIs testing ground, where you can upload files via a field or drag and drop.

Web Browser support

At this moment, this works in Firefox 3.6+ and latest Google Chrome and Safari. In Safari, though, it does support the API but seems unable to read out any information about the files. It is also supported in the preview versions of IE10.

Taking it to the next level

After you have read out the necessary data about the file(s), you can get the binary data by using a FileReader object and then use the XMLHTTPRequest object to post it to a web server. More information about that can be found in the FileReader documentation and in Paul Rouget’s article Interactive file uploads with Drag and Drop, FileAPI and XMLHttpRequest.

Happy filing! :-)

11 Comments

  • Remy Sharp says:

    So far, unless you're in Firefox, I've not found the (limited) File API to be useful. In fact the properties you've listed aren't useful for a file upload either (unless I've missed something?) – this is because the filename doesn't include the directory, which means I can't pop it in a file input type in the background.

    Where I have seen it to be powerful is when the File API is better implemented and includes support like <code>readAsDataURL</code> – which Firefox does have. Then we can start processing files in the browser – what the File API is really powerful for.

    If on the other hand you want to just get the file location, that's available in some of the content types in a drop operation, usually sitting in the <code>text/uri-list</code> content type via <code>event.dataTransfer.getData('text/uri-list')</code> (you can have a play here). IIRC there's an array in some cases too, allowing for multiple file uploads.

  • Andy L says:

    I must say I find the File API extremely useful as well.

    In fact, as I see it, it’s one of the most useful features of the whole “HTML5″ initiative, together with HTML5 Forms. The emphasis here is on *usefulness*.

    That said, Google Chrome does NOT yet support the File API as extensively as Firefox does.

    Robert, some typos in your post:
    CHrome
    FileReder

  • Andy L says:

    Google Chrome 5 is/was supposed to support the File API to a much higher degree than Google Chrome 4. Does anyone have any info on this?

  • Robert Nyman says:

    Remy,

    I find it quite useful, to be honest. Imagine a form where you can upload content: now we can easily determine what file types are being uploaded and block/inform the user about that, we can display the file names in a nice list of our choosing and we can warn the user if the file size is too big.

    Full path to files aren't needed: if you look at Paul's example with using <code>FileReader</code> and using methods like <code>readAsBinaryString</code> you can, in an asynchronous manner, upload files through the <code>XMLHTTPRequest</code> object.

    If you want to work with <code>readAsDataURL</code> or pull full paths, however, you can do that too.

    Just a lot of nice options to handle files that we didn't have before. :-)

  • Robert Nyman says:

    Andy L,

    Absolutely, I think it’s very easy to connect to real-world usage right away. Firefox does have more extensive support to my knowledge, yes.

    In the version I have been testing in, from their dev channel (version 5.0.375.9), it seems to have pretty good support (not sure what the state was in version 4), but I haven’t tested all of it to say more than that.

  • Halans says:

    I believe there's a typo, first input id should be

    input id="files-upload"

    No?

  • Robert Nyman says:

    Andy L, Halans,

    Yes, thanks about the typos – I was a little bit stressed when I wrote it. :-)

  • [...] Using the File API for reading file information & multiple file uploads – another sister speci… [...]

  • Rafael says:

    It seems to me that one major drawback is that it is not possible to remove Files from the FileList object. So if the user initially selects 10 files for upload, but then decides to remove one, this can’t be done. You can fake it by visually removing it from the page (assuming, of course, you’ve provided some sort of visual feedback of which files are about to be uploaded). But once the form is submitted, all 10 will be uploaded.

    It would be that much powerful if this was implemented and I can’t see how this simple yet important feature has been overlooked.

  • Robert Nyman says:

    Rafael,

    Good point. I haven’t tested, but I guess in the files collection, especially when it comes to uploading files, when you iterate over them you can skip over that specific one and not upload it.

  • [...] it quite interesting is all the new support for file interaction. I’ve written about the File API and reading file information before, and I thought I’d expand on that and add uploads and progress [...]

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>