Skip to main content

File upload and Progress events with HTML5 XmlHttpRequest Level 2

The XmlHttpRequest Level 2 specification adds several enhancements to the XmlHttpRequest object. Last week I had blogged about cross-origin-requests and how it is different from Flash\Silverlight's approach.  With Level 2 specification one can upload the file to the server by passing the file object to the send method. In this post I'll try to explore uploading file using XmlHttpRequest 2 in conjunction with the progress events. I'll also provide a description on the new HTML5 tag - progress which can be updated while the file is being uploaded to the server. And of course, some ColdFusion code that will show how the file is accepted and stored on the server directory.

Progress Tag:

HTML5 has introduced several new elements to the language and one of them the progress element. This element is used to show a progress bar on the web page. This tag comes handy for describing any work in progress. It can be used to describe the progress of a time consuming task.The progress element comes with two attributes: value and max. The value attribute is used to indicate the current value of progress and the max attribute is used to describe completion value.

<progress id="progressBar" max="100" value="0"></progress>

XmlHttpRequest Progress Events:

The only event listener that was available with XmlHttpRequest was the readystatechange event listener. Now with the advent of HTML5, several event listeners have been added to the XmlHttpRequest Interface - loadstart, progress, load, abort, error, timeout and loadend. The loadstart event is triggered when the request is initiated by the client. The progress event is triggered once the loadstart event has been dispatched.

In this example, I'll try to upload a file (text, image, mp3) using XmlHttpRequest and show the progress for the same by updating the progressbar (progress tag) using the progress event handler. With Level 2 specification one can now pass ArrayBuffer, Blob, File and FormData objects to the send method.

The input tag with the type file can be used to select a file that needs to be uploaded to the server (<input id="fileUpload" type="file" />). Once the file is selected, a POST request can then be made to the server and the file object can be passed as an argument to the send method:

function uploadFile(){
    var filesToBeUploaded = document.getElementById("fileControl");
    var file = filesToBeUploaded.files[0];
    var xhrObj = new XMLHttpRequest();
    xhrObj.upload.addEventListener("loadstart", loadStartFunction, false);
    xhrObj.upload.addEventListener("progress", progressFunction, false);
    xhrObj.upload.addEventListener("load", transferCompleteFunction, false);"POST", "upload.cfm", true);
    xhrObj.setRequestHeader("Content-type", file.type);

As observed in the above code, event listeners are added for loadstart, progress and load events. These events are added for the upload attribute of XmlHttpRequest object. The Content-type header is set to the value of file.type. This is required to let the server know the mime type of file being transferred. Also, the header X_FILE_NAME with the value of is specified. The file object is then passed to the send method of the XmlHttpRequest object.

The loadstart event is triggered once a request to send a file to the server is initiated. Once this function has been dispatched the progress event is triggered indicating that the file is being uploaded to the server:

function progressFunction(evt){
    var progressBar = document.getElementById("progressBar");
    var percentageDiv = document.getElementById("percentageCalc");
    if (evt.lengthComputable) {
        progressBar.max =;
        progressBar.value = evt.loaded;
        percentageDiv.innerHTML = Math.round(evt.loaded / * 100) + "%";

The progress event is triggered as and when some data is uploaded to the server. This depends on the size of file that is being transmitted. The progressFunction defined above, takes an argument of type ProgressEvent. The ProgressEvent Interface defines the attributes - lengthcomputable, loaded and total. The lengthcomputable attribute is used to find whether the progress is an indeterministic or deterministic one. In this case the size of the file being uploaded is known and hence the lengthcomputable attribute will be set to true. The other attributes loaded and total are used to indicate the number of bytes uploaded of the total number of bytes. This data is then used to update the progress tag attributes value and max.

Server side code:

The server-side code is as simple as it can get:

<cfset headerdata="getHTTPRequestData().headers">
<cfset content="getHTTPRequestData().content">
<cfset filePath = expandPath(".") & "/Uploaded/" & headerData.X_FILE_NAME >
<cfset content="content" filepath="filepath" filewrite="filewrite">

The header X_FILE_NAME would contain the name of the file that is being sent from the client. The file content is available in the request data and the same is accessed using getHTTPRequestData().content.


You can download the source code from -
Also, take a look at my post 'Uploading chunks of a large file using XHR2', which talks about how you can upload large files to a server that has a post parameter limit.


  1. Do you have a link for the demo? dowload?

  2. I don't have a demo page. However, if you want the source code for the File upload, let me know your mail id. I'll send it to you.

  3. This is my email address...please send the source code at the earliest...thanking u...

    This is my email address...
    please send the source code at the earliest...thanking u...

  5. Thnx a lot for sending the source code...

  6. Very interesting post. PLease could you send me the source code too. My email address is paul_edward at



  7. This is my email please send on this .

  8. Doesn't work for binary data such as a .png file.

  9. I was able to upload a png file. On which browser you are trying this example?

  10. Hi, could you send me that source code please? email is: grorog ( at )

  11. Hii Sagar..
    Hi, could you send me that source code please?

  12. I'm interested in checking out the source as well.

  13. I've updated the post. You can download the source code from here

    can u send mail for me?

  15. Sweet !!! Thank you and for the demo files too !!!

  16. If you want to upload a large file in fragments using XHR2, see my post -

  17. Thanks for the code Sagar, I have a question.. this works fine on my CF9 but on CF10 I get progress bar 15% or whatever the first progress (depending on the size of the file) and then it aborts. I added event handler for error .. it aborts with an error. I see status 2 and nothing about error. Tomorrow, I will check CF logs but on top of your head.. any suspect(s)?

  18. This might have to do with the post parameter limit. If you're uploading a large file you might get a 400 error. To address this, you need upload it in chunks. Refer to my post - 'Uploading chunks of a large file using XHR2' here -

  19. please send demo ..... thanks


Post a Comment

Popular posts from this blog

Custom validation messages for HTML5 Input elements using the constraint validation API

HTML5 has introduced several input types such as EMAIL, URL, RANGE, SEARCH, DATE, TIME, etc,. Most of the modern browsers have implemented them and are ready to be used in a HTML document. Another exciting feature introduced in HTML5 is the form validation. Instead of writing JavaScript to validate users input, browsers can now validate it and show an appropriate message if the validation fails. The validation message is shown in line with the field for which the validation has failed. The default error message is shown when the validation fails. In this post I'll explain how these error messages can be changed.

Adding beforeRender and afterRender functions to a Backbone View

I was working on a Backbone application that updated the DOM when a response was received from the server. In a Backbone View, the initialize method would perform some operations and then call the render method to update the view. This worked fine, however there was scenario where in I wanted to perform some tasks before and after rendering the view. This can be considered as firing an event before and after the function had completed its execution. I found a very simple way to do this with Underscore's wrap method.

A cheat sheet of keyboard shortcuts in ColdFusion Builder

In my last post I have explained about keyboard shortcuts in ColdFusion Builder 2.0. This blog post contains a list of all shortcut keys and I have listed these keyboard shortcuts based on the categories that it falls into. Well, this post was not planned since users can easily get to know the keyboard shortcuts by navigating to the preferences (ColdFusion -> Profiles -> Keys). However, I met Joshua at Scotch on the rocks in Edinburgh and he suggested that it would be nice to have the list of keyboard shortcuts handy. So this post is for those who would like to have the list with them and refer it whenever required.

Keyboard shortcuts for inserting text:

These are the keyboard shortcuts which are used to insert some text into the editor:

CommandKeyboard shortcuts on WindowsKeyboard shortcuts on MacInsert anchor tagCTRL + T, LCMD + T, LInsert bold tagCTRL + T, BCMD + T, BInsert br tagCTRL + T, RCMD + T, RInsert cfabortCTRL + T, ACMD + T, AInsert cfdumpCTRL + T, DCMD + T, DInsert cfs…