使用PHP和jquery在下载文件时显示下载进度

4
我正在使用PHP和jQuery开发下载管理器。
需要一个脚本,可以下载文件并显示下载进度。
我尝试了以下方法,但它不起作用。
jQuery
function downloadFile(){
    var fileNameDownloading ="somefile.mp3"
    var oReq = new XMLHttpRequest();    
    oReq.addEventListener("progress", updateProgress, false);
    var params = "filename="+fileNameDownloading;   
    oReq.open("GET", "scripts/download.php?"+params, true);
    oReq.responseType = "blob";//blob arraybuffer

    function updateProgress (e) {
        console.log(e.loaded/e.total);
    }
    oReq.send();    
}

PHP

<?php
$file = $_GET['filename'];
$fileSize = get_size($file);
$packetSize = 262144;//2000
if($packetSize > $fileSize){
    $packetSize = $fileSize;
}
download($file,$packetSize);


function download($file,$chunks){
    set_time_limit(0);
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-disposition: attachment; filename='.basename($file));
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Expires: 0');
    header('Pragma: public');
    $size = get_size($file);
    header('Content-Length: '.$size);

    $i = 0;
    while($i<=$size){
        //Output the chunk
        get_chunk($file,(($i==0)?$i:$i+1),((($i+$chunks)>$size)?$size:$i+$chunks));
        $i = ($i+$chunks);
    }

}

//Callback function for CURLOPT_WRITEFUNCTION, This is what prints the chunk
function chunk($ch, $str) {
    
    print($str);
    return strlen($str);
}

//Function to get a range of bytes from the remote file
function get_chunk($file,$start,$end){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $file);
    curl_setopt($ch, CURLOPT_RANGE, $start.'-'.$end);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
    curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'chunk');
    $result = curl_exec($ch);
    curl_close($ch);
}

//Get total size of file
function get_size($url){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_exec($ch);
    $size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
    return intval($size);
}
?>

寻求建议,如何使用PHP和JavaScript下载文件并显示下载进度。谢谢。


你真的做不到那样。一旦浏览器开始下载文件,我相信你无法跟踪它。而且为什么要这样做呢?每个浏览器都有某种形式的进度指示在进行中吧? - php_nub_qq
这不是jQuery,它是纯JavaScript。 - L105
嗨,php_nub_qq,进度条的作用是在用户点击下载时,在同一屏幕中为所有用户提供统一的感觉,因为不同的浏览器具有不同的下载进度条和不同的位置。 - Ajit Kumar
嗨,L105。是的,这是纯JavaScript,我认为jQuery可以提供一些更好的解决方案,所以我保持了jQuery选项开放。 - Ajit Kumar
嗨,Ajit,我的回答能够帮助你解决问题了吗?或者你已经解决了你的问题吗? - jth_92
2个回答

1

有两种可行的方法,包括使用轮询或 uploadProgress ajaxSubmit 选项。

使用 ajax / javascript 轮询,您将每秒设置一个 setTimeout,调用服务器文件并查看已写入服务器的数据量。本文应提供良好的轮询示例和描述。回调将根据文件大小设置进度。

第二种方法是使用 uploadProgress ajaxSubmit 选项。此文章将为您提供如何设置此选项的良好教程。

以下是代码示例:

jQuery:

$(document).ready(function() {  
var options = { 
        target:   '#output', 
        beforeSubmit:  beforeSubmit,
        uploadProgress: OnProgress, //upload progress callback 
        success:       afterSuccess,
        resetForm: true  
    }; 
    
 $('#MyUploadForm').submit(function() { 
        $(this).ajaxSubmit(options);            
        return false; 
    });
});

function OnProgress(event, position, total, percentComplete)
{
    //Progress bar
    progressbar.width(percentComplete + '%') //update progressbar percent complete
    statustxt.html(percentComplete + '%'); //update status text
    if(percentComplete>50)
        {
            statustxt.css('color','#fff'); //change status text to white after 50%
        }
}

HTML:

<div id="upload-wrapper">
<div align="center">
<h3>Ajax Image Uploader with Progressbar</h3>
<span class="">Image Type allowed: Jpeg, Jpg, Png and Gif. | Maximum Size 1 MB</span>
<form action="processupload.php" onSubmit="return false" method="post" enctype="multipart/form-data" id="MyUploadForm">
<input name="ImageFile" id="imageInput" type="file" />
<input type="submit"  id="submit-btn" value="Upload" />
<img src="images/ajax-loader.gif" id="loading-img" style="display:none;" alt="Please Wait"/>
</form>
<div id="progressbox" style="display:none;"><div id="progressbar"></div ><div id="statustxt">0%</div></div>
<div id="output"></div>
</div>
</div>

CSS
#progressbox {
border: 1px solid #0099CC;
padding: 1px; 
position:relative;
width:400px;
border-radius: 3px;
margin: 10px;
display:none;
text-align:left;
}
#progressbar {
height:20px;
border-radius: 3px;
background-color: #003333;
width:1%;
}
#statustxt {
top:3px;
left:50%;
position:absolute;
display:inline-block;
color: #000000;
}

0

看看这个stackoverflow上的答案。它确实有效,链接也不会很快失效。

以下是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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接