Checking file uploads in JavaScript

One of the problems many people face with their websites is handling file uploads from users – given the opportunity, people tend to just try uploading any old thing. On a site that I run, people can upload their own photos, which we then scale to a maximum of 600 pixels in each direction.

We ask them not to upload huge files, because it takes a long time, it’s a pain to have to resize them – especially in PHP, which can run into memory issues sometimes – and since they’re only viewed online, multi-megabyte images just aren’t needed.

Of course, that doesn’t stop people from just trying to upload 6MB image files, then complaining that it doesn’t work. Or from trying to upload a variety of formats when – for the sake of simplicity – we’d rather just stick with JPG.

Traditionally, you can’t check information about a file until it’s been uploaded, because JavaScript doesn’t have full access to the local hard disk, for security reasons. So, you have to allow someone to spend ages on a slow link uploading that massive file, so that your script can then say “Sorry, it was too big” or “Sorry, it was in the wrong format.”

It’s hardly a good user experience. The alternative is to use a Flash uploader, which can check the file before sending it; there are off the shelf applications that you can use to do that, including some from sites like DMXZone.com if you simply want something that can be dropped onto the page in DreamWeaver.

HTML5

Flash isn’t always convenient, of course, though it’s still very widely deployed. But there is an alternative, which is some extensions to Javascript that go along with HTML5 and are supported in many of the latest browsers. There are a few examples around the net using the new window.File attributes, which I drew on in coming up with the code here that I’ve used for photo uploads on one of my sites.

Essentially, I want to make sure that, where possible, I only allow people to upload a file that’s less than 800k, and is a JPG. The code here is a simplified version of what I’m using, which demonstrates the basics of how you can check a file’s size and type before allowing the user to submit the form.

 

Unable to upload
How Firefox informs the user they've selected an inappropriate file

The files attribute of our upload form is a list of file names, so files[0] is the first file. Each one individually has properties including name, for the filename, type for the MIME type and size, for the size in bytes. Here’s the Javascript:
function validateFile() {
if ( window.File) {
thisFile = document.getElementById('photo1').files[0] ;
sizeError = false ; formatError = false ;
var status = 'Ready to upload' ;
if ( thisFile.size > 819200 ) {
sizeError = true ;
}
if ( thisFile.type != 'image/jpeg' ) {
formatError = true ;
}
if ( sizeError || formatError ) {
errorMsg = 'Sorry; ' + thisFile.name + ' cannot be uploaded.' ;
if ( sizeError ) {
errorMsg = errorMsg + ' File is more than 800k. Please resize and try again.' ;
}
if ( formatError ) {
errorMsg = errorMsg + ' File is not a JPG. Please convert to JPG format and try again.' ;
}
status = 'Cannot be uploaded' ;
alert(errorMsg) ;
}
statusInfo = document.getElementById('status1') ;
statusInfo.innerHTML = thisFile.name + ': ' + status
}
}

You’ll need to alter the form field definition, too, so that it looks something like this:

<input id="photo1" name="imageFile" type="file" /><span id="status1"> </span>

The span tag afterwards allows the name of the file and the status to remain on the page, after any alert has been dismissed; I use that because on some pages, people can upload multiple files, and a version of the script validates each one when it’s changed, and also adds a button to reset each of the file selections. Here are two grabs that show how that looks:

File can't be uploaded
The script shows the name of the file and the status
File ready to upload
This file is ready to upload

The full version also keeps track, via an array of Boolean variables, of which of the file fields on the page has an invalid file selected, and sets the ‘display’ style attribute of the page’s Submit button to ‘none’ so that the user can’t even submit the form when an invalid file has been chosen.

Apologies, by the way, for the awkward spacing.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.