問題描述
我正在嘗試使用 Ajax 下載文件并顯示自定義下載進(jìn)度條.
問題是我不明白該怎么做.我編寫了代碼來記錄進(jìn)度,但不知道如何啟動(dòng)下載.
注意:文件屬于不同類型.
提前致謝.
JS
//文件下載filelist.on('click', '.download_link', function(e){e.preventDefault();var id = $(this).data('id');$(this).parent().addClass("download_start");$.ajax({xhr: 函數(shù) () {var xhr = 新窗口.XMLHttpRequest();//處理下載進(jìn)度xhr.addEventListener("進(jìn)度", function (evt) {如果(evt.lengthComputable){var percentComplete = evt.loaded/evt.total;console.log(percentComplete);}}, 錯(cuò)誤的);返回xhr;},完成:函數(shù)(){console.log("請求完成");}})});
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">'.日期(M d,Y",$file_upload_time).' • '.human_filesize($file_size) .'</div></div><div class="right_wing"><div 類="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="刪除這個(gè)?"></i></a></div></div></li>
如果您想向用戶顯示下載過程的進(jìn)度條 - 您必須在 xmlhttprequest 中進(jìn)行下載.這里的問題之一是,如果您的文件很大 - 它們將在瀏覽器將它們寫入磁盤之前保存在瀏覽器的內(nèi)存中(使用常規(guī)下載文件時(shí)直接保存到磁盤,這樣可以在大文件上節(jié)省大量內(nèi)存).
另一個(gè)需要注意的重要事項(xiàng) - 為了使 lengthComputable
為真 - 您的服務(wù)器必須發(fā)送帶有文件大小的 Content-Length
標(biāo)頭.
這里是javascript代碼:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div id="a1" data-filename="filename.xml">點(diǎn)擊下載</div><腳本>$('#a1').click(function() {var that = this;var page_url = 'download.php';var req = new XMLHttpRequest();req.open("POST", page_url, true);req.addEventListener("進(jìn)度", function (evt) {如果(evt.lengthComputable){var percentComplete = evt.loaded/evt.total;console.log(percentComplete);}}, 錯(cuò)誤的);req.responseType = "blob";req.onreadystatechange = function () {如果(req.readyState === 4 && req.status === 200){var filename = $(that).data('filename');if (typeof window.chrome !== 'undefined') {//鉻版本var link = document.createElement('a');link.href = window.URL.createObjectURL(req.response);link.download = 文件名;鏈接.click();} else if (typeof window.navigator.msSaveBlob !== 'undefined') {//IE版本var blob = new Blob([req.response], { type: 'application/force-download' });window.navigator.msSaveBlob(blob, 文件名);} 別的 {//火狐版本var file = new File([req.response], filename, { type: 'application/force-download' });window.open(URL.createObjectURL(file));}}};req.send();});</腳本>
下面是你可以使用的 php 代碼示例:
<塊引用>
請注意,我添加了一個(gè)睡眠來模擬慢速連接以在 localhost 上進(jìn)行測試.
您應(yīng)該在生產(chǎn)中刪除此 :)
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) . ' • ' . 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>
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 :)
這篇關(guān)于顯示使用 XHR2/AJAX 下載文件的進(jìn)度條的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!