HTML5 File Upload with Progress Bar Using jQuery

XMLHttpRequest Level 2, HTML5 File API and Progress event work together to provide a completely new file upload model. There are numerous benefits to this new model compared to the old multi-part form approach.

  • You can upload files using Ajax.
  • You can show progress indicator.
  • The server side code becomes a lot simpler.

Every new web application should take a look the new approach.

Unfortunately, jQuery is somewhat lagging in its support for the new approach. There are a few specific work arounds you have to take to make things to work. By work around, I mean, things that you must do that could have been easily taken care of by jQuery.

Note: If you are not using jQuery and just want to know how to upload file using XMLHttpRequest Level 2, then read this other article. The article below assumes that you know the fundamentals of XMLHttpRequest Level 2 already and just want to know how to use jQuery to do the work.

Let’s start with the form. There are many ways to get the list of files to upload. You can use drag and drop. Or, as is the case in this article, we will use a simple input of type file. Also, to display progress, you can use the HTML5 progress element. But, for a better look, we will choose to use jQuery UI’s progress widget. Our HTML markup will be very simple.

<input type="file" id="fileToUpload"/><br/>
<div id="progressbar"></div>
<button id="upload_btn">Start Uploading</button>

From the ready function, we setup the UI. This is just regular jQuery stuff and we are not doing anything with file upload API yet.


All the action happens from the upload() method.

function upload(){
    var fileIn = $("#fileToUpload")[0];
    //Has any file been selected yet?
    if (fileIn.files === undefined || fileIn.files.length == 0) {
        alert("Please select a file");

    //We will upload only one file in this demo
    var file = fileIn.files[0];
    //Show the progress bar

        url: "MediaUploader?fileName=" + + "&mimeType=" + file.type,
        type: "POST",
        data: file,
        processData: false, //Work around #1
        contentType: file.type, //Work around #2
        success: function(){
        error: function(){alert("Failed");},
        //Work around #3
        xhr: function() {
            myXhr = $.ajaxSettings.xhr();
                myXhr.upload.addEventListener('progress',showProgress, false);
            } else {
                console.log("Upload progress is not supported.");
            return myXhr;

Alright, let’s go through the work arounds.

  1. We must set processData to false. Here’s why. We set the File object as the data field. jQuery doesn’t recognize File object and tries to use it to generate regular form post data, which obviously fails.
  2. The content type needs to be set correctly to the MIME type of the file. Otherwise, some browsers will set it to “application/x-www-form-urlencoded”. The server will then try to parse the request body as form input, which will obviously fail.
  3. This is the big one. jQuery provides no way of attaching a “progress” event listener for the XMLHttpRequest object. The work around is to register your own XMLHttpRequest object creation method and attach the event handler from there.

Now, all there is left to do is show the progress.

function showProgress(evt) {
    if (evt.lengthComputable) {
        var percentComplete = (evt.loaded / * 100;
        $('#progressbar').progressbar("option", "value", percentComplete );

The server side is, of course, quite straightforward. Your best bet is to write a Servlet. Various JAX-RS implementations provide custom extensions to handle HTML5 file upload. You can also use that option if you are not worried about getting locked down to an implementation. Here, we will use a Servlet.

protected void doPost(HttpServletRequest request, HttpServletResponse response) 
  throws ... {
    String fileName = request.getParameter("fileName"); 
    InputStream is = request.getInputStream();
    //Read the file contents from the input stream
    byte buff[] = new byte[256];
    int len;

    while ((len = > 0) {

10 thoughts on “HTML5 File Upload with Progress Bar Using jQuery

  1. Thanks for this, helped me loads, but one question, how do I handle the fallback to regular post if user doesn’t have XHR supported? Like do normal post and show preloader instead of progress bar?

    • @askibinski I recommened that you read about the jQuery Ajax API. xhr.send() is called by $.ajax() as you have guessed.

      $.ajaxSettings.xhr() is what we are calling here to create a new XHR object. Normally, this not something one needs to do when using $.ajax(). We need to do this so that we can attach a progress event handler.

  2. Thank You So Much!!!!!!!!!!!!!!!!
    I have been searching about uploading files to web service and this post helped me🙂
    Now i want to know how to upload multiple files…

  3. This is good one.
    But setting this xhr options cause one extra “options” method call, which i don’t want. So, do you know any way to prevent this call and also get progress of upload?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s