How to get the progress of an upload or download with jQuery AJAX

Although some browsers, show the progress in right bottom corner of the screen, you may want to retrieve these values and use them in your project to show your user the progress of the download or upload with your own UI.

In order to retrieve the progress of an upload or download (request) with ajax, we need to manipulate the global xhr (XMLHttpRequest) object in the document.

If we don't use jQuery (vanillaJS), the algorithm is really simple and easy to understand:

function updateProgress(evt){
  if (evt.lengthComputable){
     var percentComplete = (evt.loaded / evt.total)*100;  
      console.log(percentComplete+"% completed");
   } 
}

var request = new XMLHttpRequest(); 
request.onprogress=updateProgress;

The onprogress event will trigger the updateProgress function of the request (both download and upload events

But if we use jQuery we need to use the xhr option which can be setted in the ajax construction :

$.ajax({
    xhr: function(){
       var xhr = new window.XMLHttpRequest();
         // Handle progress
         //Upload progress
       xhr.upload.addEventListener("progress", function(evt){
           if (evt.lengthComputable) {
              var percentComplete = evt.loaded / evt.total;
              //Do something with upload progress
              console.log(percentComplete);
           }
       }, false);
       //Download progress
       xhr.addEventListener("progress", function(evt){
            if (evt.lengthComputable) {
              var percentComplete = evt.loaded / evt.total;
              //Do something with download progress
              console.log(percentComplete);
            }
       }, false);

       return xhr;
    },
    complete:function(){
        console.log("Request finished.");
    }
});

The ProgressEvent.lengthComputable read-only property is a Boolean flag indicating if the resource has a length that can be calculated. If not, the ProgressEvent.total property has no significant value and we cannot retrieve the progress of the process, in both cases, the progress will be easily retrieved.

Older jQuery version

If you're using jQuery <= 1.5, you may want to use the following code instead as the xhr property is not supported on these versions.

$.ajax({
    type: 'POST',
    url: "/",
    data: {},
    beforeSend: function(XMLHttpRequest){
        //Upload progress
        XMLHttpRequest.upload.addEventListener("progress", function(evt){
            if (evt.lengthComputable) {  
                var percentComplete = evt.loaded / evt.total;
                //Do something with upload progress
            }
        }, false); 
        //Download progress
        XMLHttpRequest.addEventListener("progress", function(evt){
            if (evt.lengthComputable) {  
                var percentComplete = evt.loaded / evt.total;
                //Do something with download progress
            }
        }, false); 
    },
    success: function(data){
        //Do something success-ish
    }
});

The listener will be appended directly to the XMLHttpRequest object which is retrieven as first parameter on the beforeSend callback of the $.ajax call.

Become a more social person