FileReader API

By  on  

As broadband speed continues to get faster, the web continues to be more media-centric.  Sometimes that can be good (Netflix, other streaming services), sometimes that can be bad (wanting to read a news article but it has an accompanying useless video with it).  And every social service does anything it can to display an image with any user upload.

One thing I hated about working with user-provided files was having to host them on a server somewhere:  the uploaded files take up disk space and in some cases become a security concern....until now.  The FileReader API allows you to access user files and their content from their machine without needing to upload to your server.

The HTML

The FileReader API works off of the File API premise and thus requires a input[type="file"] element:

<-- Let's go big and enable for multiple file uploads -->
<input type="file" id="upload-file" multiple />

<-- We'll display the image in this DIV -->
<div id="destination"></div>

Read my File API post to learn more about what it provides, like location, size, type, and more.

The JavaScript

This example calls for an image to be chosen within the input; once an image is chosen by the user on their machine, the image is to be displayed on the page:

document.getElementById('upload-file').addEventListener('change', function() {
	var file;
	var destination = document.getElementById('destination');
	destination.innerHTML = '';

	// Looping in case they uploaded multiple files
	for(var x = 0, xlen = this.files.length; x < xlen; x++) {
		file = this.files[x];
		if(file.type.indexOf('image') != -1) { // Very primitive "validation"

			var reader = new FileReader();

			reader.onload = function(e) {
				var img = new Image();
				img.src = e.target.result; // File contents here

				destination.appendChild(img);
			};
			
			reader.readAsDataURL(file);
		}
	}
});

This example uses FileReader's readAsDataURL method to convert the file contents to a base64-encoded string which can be used as an image data URI for the src attribute.  Other FileReader read types include readAsText, readAsArrayBuffer, and readAsBinaryString.

With this API you can avoid server uploads of raw user files, which I love.  You can also pre-treat content before you manually upload user content to your servers.  An example of where this is used is the smartcrop.js testbed.  Please share other ideas for usage if you have them!

Recent Features

  • By
    How I Stopped WordPress Comment Spam

    I love almost every part of being a tech blogger:  learning, preaching, bantering, researching.  The one part about blogging that I absolutely loathe:  dealing with SPAM comments.  For the past two years, my blog has registered 8,000+ SPAM comments per day.  PER DAY.  Bloating my database...

  • By
    Send Text Messages with PHP

    Kids these days, I tell ya.  All they care about is the technology.  The video games.  The bottled water.  Oh, and the texting, always the texting.  Back in my day, all we had was...OK, I had all of these things too.  But I still don't get...

Incredible Demos

  • By
    Create Digg URLs Using PHP

    Digg recently came out with a sweet new feature that allows users to create Tiny Digg URLs which show a Digg banner at the top allowing easy access to vote for the article from the page. While I love visiting Digg every once in a...

  • By
    Send Email Notifications for Broken Images Using MooTools AJAX

    One of the little known JavaScript events is the image onError event. This event is triggered when an image 404's out because it doesn't exist. Broken images can make your website look unprofessional and it's important to fix broken images as soon as possible.

Discussion

  1. Daniel k

    How’s browser support looking for this Api?

  2. James

    Data URLs have a size limit, wouldn’t this impede larger uploads?

    A possibly better solution is to use URL.createObjectUrl which can take the file directly and provide a URL for it, falling back to data URLs if unsupported.

  3. Tolga

    I’d been looking for this all along. It’s good that I checked the article :)

  4. The demo doesn’t work on smartphone!

    Nexus 5 with native chrome browser and Android 6.0.

  5. Mohamed hussain

    I found in depth file api in nicholas zakas blog…but still not useful in case of invalid server validation….and large file upload

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!