Using HTML5 and the Blueimp jQuery-File-Upload Plugin To Upload Large Files

By Robert Gravelle

One of the most appealing features of the HTML5 File API is that you can pass the file data to the XmlHttpRequest object for uploading to a server. That gives you several advantages. First, it makes the process asynchronous, which means that your browser will still work while you wait for the upload to complete. Second, by taking advantage of the File API's chunking capabilities, you can process large binary files that you might not otherwise be able to, due to both browser and/or server-side restrictions.

I was working on an HTML5 upload page using the FileReader and Ajax when I realized that the server-side coding would take more effort than I had anticipated. Large files were particularlarly problematic due to the asynchronous nature of both the FileReader and XMLHTTPRequest objects, which caused both chunks and files to be sent out of sequence. I would therefore need my server-side process to be able to create temporary files and keep track of the chunks so that they could be reassembled into the original files.

In an effort to keep the scope of my little project to a manageable size, I went on the hunt for a library to help with the server-side part. After a little googling, I found just the thing. It's called the blueimp jQuery-File-Upload plugin, by Sebastian Tschan. The rest of this article explains how to use it in your web pages, while future instalments will cover more advanced topics like event handlers and working with the XHR response.

What Is It?

The jQuery-File-Upload plugin achieves cross-browser compatibility by using the FileReader and XMLHttpRequest objects in browsers that support them and an Iframe Transport module for browsers like Microsoft Internet Explorer and Opera, which do not yet support XHR file uploads. The client-side code is extended jQuery, while the server-side components include PHP, Google App Engine (GAE) for Python, and GAE-Go. I chose to use the PHP component for the purposes of my project because both my WAMP and Sambar servers support PHP.

The plugin comes in two flavors: the basic plugin implements the file upload process described above, while the UI version adds a complete User Interface and advanced functionality such as server-side image rescaling for thumbnail previewing. We're going to keep it simple for now and "plugin" the upload functionality in our own page, without the UI components.

Acknowledgments

To give credit where credit is due, I should mention that my test page is based largely on Phil Parsons excellent Ajax upload with XMLHttpRequest level 2 and the File API blog post. The main difference between his application and my own is the addition of jQuery and the blueimp jQuery-File-Upload plugin. Both his and my web page allow the user to select multiple files at a time, display information about them, and provide previews for images. The file selection is done using a file input control (Mr. Parson's demo also accepts files via Drag & Drop). Another <DIV> contains the file info:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <link rel="stylesheet" type="text/css" href="style/default.css" media="screen" />
        <title>JavaScript File API and Ajax uploading Demo</title>
    </head>
    <body>
        <div id="wrap">
            <h1>JavaScript File API and Ajax uploading Demo</h1>
            <h2>Choose a file to upload:</h2>
            <input id="file_upload" type="file" name="files[]" />

            <div id="files">
                <h2>File Preview</h2>
                <ul id="filePreview"></ul>
                <a id="remove" href="#" title="Remove file">Remove file</a>
            </div>
        </div>
    </body>
</html>

Script References

The jQuery-File-Upload front-end code is spread across four external JS files, two of which are not included in the download package and are hosted on the googleapis.com site. Here is what is contained in each:

  • jquery.min.js: The hosted minified jQuery library.
  • jquery-ui.min.js: A hosted extention of the basic fileupload widget. It also adds a complete user interface based on jQuery templates.
  • jquery.fileupload.js: The basic jQuery-File-Upload plugin, used to enhance the file upload process.
  • jquery.iframe-transport.js: Adds iframe transport support to jQuery.ajax() for browsers that don't support the File API.

In addition to these four files, we'll need to add two more of our own:

  • json_parse.js: Douglas Crockford's JSON parser. It along with other JSON parsers are available from Github.
  • upload.js: It will house all of our client-side code.
<html>
    <head>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
        <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
        <script src="js/jquery.fileupload.js"></script>
        <script src="js/jquery.iframe-transport.js"></script>
        <script src="js/json_parse.js"></script>
        <script src="js/upload.js"></script>

Minimal Setup Instructions

The plugin is instanciated when you call fileupload() from a jQuery file upload widget. By building our own UI, as we have done here, we can use the basic plugin version with only a few options. At a minimum, you need to and pass it a options object that contains the server component url, some files, and perhaps a function to run once the upload has completed. To convert any HTML element into a jQuery widget, call it with any jQuery DOM function that returns a jQuery widget. The $('#elementid') function is usually the simplest. Here's a very simple call to fileupload() which adds the uploaded file's name to the document once it's done:

$('#file_upload').fileupload({
    url: 'php/index.php',
    done: function (e, data) {
        $.each(data.result, function (index, file) {
            $('<p/>').text(file.name).appendTo('body');
        });
    }
});

And yes, we didn't even code an onchange event handler for the file input element!

Conclusion

Uploading files in HTML5 is a complex enough undertaking that it can really pay off to use a plugin rather than try to write everything yourself. Although we only did a small amount of coding here today, the next article will be much more code intensive as we'll be writing the event handlers to display file information, image thumbnails, and individual file progress bars.



Make a Comment

Loading Comments...

  • Web Development Newsletter Signup

    Invalid email
    You have successfuly registered to our newsletter.
  •