Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
110
rated 0 times [  116] [ 6]  / answers: 1 / hits: 40036  / 8 Years ago, tue, september 20, 2016, 12:00:00

I am trying to download files using Ajax and show a custom download progress bar.



The problem is I can't understand how to do so. I wrote the code to log the progress but don't know how to initiate the download.



NOTE: The files are of different types.



Thanks in advance.



JS



// Downloading of files
filelist.on('click', '.download_link', function(e){
e.preventDefault();
var id = $(this).data('id');
$(this).parent().addClass(download_start);

$.ajax({
xhr: function () {
var xhr = new window.XMLHttpRequest();
// Handle Download Progress
xhr.addEventListener(progress, function (evt) {
if(evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
}
}, false);
return xhr;
},
complete: function () {
console.log(Request finished);
}
})
});


HTML and PHP



    <li>
<div class=f_icon><img src=' . $ico_path . '></div>
<div class=left_wing>
<div class=progressbar></div>
<a class=download_link href=# id='.$file_id.'><div class=f_name>' . $full_file_name . '</div></a>
<div class=f_time_size>' . date(M d, Y, $file_upload_time) . '&nbsp; &#149; &nbsp;' . human_filesize($file_size) . '</div>
</div>

<div class=right_wing>
<div class=f_delete>
<a class=btn btn-danger href=# aria-label=Delete data-id='.$file_id.' data-filename='.$full_file_name.'><i class=fa fa-trash-o fa-lg aria-hidden=true title=Delete this?></i>
</a>
</div>
</div>
</li>

More From » jquery

 Answers
-1

If you want to show the user a progress-bar of the downloading process - you must do the download within the xmlhttprequest. One of the problems here is that if your files are big - they will be saved in the memory of the browser before the browser will write them to the disk (when using the regular download files are being saved directly to the disk, which saves a lot of memory on big files).



Another important thing to note - in order for the lengthComputable to be true - your server must send the Content-Length header with the size of the file.



Here is the javascript code:



<script src=https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js></script>
<div id=a1 data-filename=filename.xml>Click to download</div>
<script>
$('#a1').click(function() {
var that = this;
var page_url = 'download.php';

var req = new XMLHttpRequest();
req.open(POST, page_url, true);
req.addEventListener(progress, function (evt) {
if(evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
}
}, false);

req.responseType = blob;
req.onreadystatechange = function () {
if (req.readyState === 4 && req.status === 200) {
var filename = $(that).data('filename');
if (typeof window.chrome !== 'undefined') {
// Chrome version
var link = document.createElement('a');
link.href = window.URL.createObjectURL(req.response);
link.download = filename;
link.click();
} else if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE version
var blob = new Blob([req.response], { type: 'application/force-download' });
window.navigator.msSaveBlob(blob, filename);
} else {
// Firefox version
var file = new File([req.response], filename, { type: 'application/force-download' });
window.open(URL.createObjectURL(file));
}
}
};
req.send();
});
</script>


And here is an example for the php code you can use:



<?php
$filename = some-big-file;
$filesize = filesize($filename);

header(Content-Transfer-Encoding: Binary);
header(Content-Length:. $filesize);
header(Content-Disposition: attachment);

$handle = fopen($filename, rb);
if (FALSE === $handle) {
exit(Failed to open stream to URL);
}

while (!feof($handle)) {
echo fread($handle, 1024*1024*10);
sleep(3);
}

fclose($handle);



Note that I added a sleep to simulate a slow connection for testing on localhost.

You should remove this on production :)



[#60668] Friday, September 16, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
ellisw

Total Points: 625
Total Questions: 92
Total Answers: 88

Location: Kazakhstan
Member since Mon, Sep 26, 2022
2 Years ago
ellisw questions
Mon, Aug 23, 21, 00:00, 3 Years ago
Fri, Nov 20, 20, 00:00, 4 Years ago
Sat, Jun 20, 20, 00:00, 4 Years ago
Tue, Apr 21, 20, 00:00, 4 Years ago
;