我正在尝试使用Ajax下载文件并显示自定义 下载进度栏。
问题是我不知道该怎么做。我编写了用于记录进度的代码,但不知道如何启动下载。
注意: 文件是不同类型的。
提前致谢。
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和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) . ' • ' . 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>
如果要向用户显示下载过程的进度条,则必须在xmlhttprequest中进行下载。这里的问题之一是,如果您的文件很大-它们将被保存 在 浏览器 的内存 中,然后浏览器会将它们写入磁盘(使用常规下载文件时,它们将被直接保存到磁盘中,这会保存一个大文件上的大量内存)。
要注意的另一件重要事情-为了lengthComputable使它正确-服务器必须发送Content-Length带有文件大小的标头。
lengthComputable
Content-Length
这是JavaScript代码:
<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>
这是您可以使用的php代码的示例:
<?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);
请注意,我添加了一个睡眠来模拟慢速连接以在localhost上进行测试。 您应该在生产时 删除它 :)