Show a progress bar to download files using XHR2 / AJAX

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

The problem is that I cannot figure out how to do this. I wrote code to register progress, but I don’t know how to start the download.

NOTE. 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> 
+5
source share
1 answer

If you want to show the user a graph of the progress of the download process, you must perform the download in the xmlhttprequest file. One of the problems is that if your files are large, they will be saved in the browser memory before the browser writes them to disk (when using regular files for downloading, files are saved directly to disk, which saves a lot of memory on large files).

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

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 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 sleep to simulate a slow connection for testing on localhost.
You must remove this when creating :)

+7
source

All Articles