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.