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

时间:2014-01-10 02:41:59

标签: php jquery ajax

我正在使用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);
}

&GT;

寻找建议,我们如何下载文件,并使用PHP和javascript显示下载进度。感谢

2 个答案:

答案 0 :(得分:-1)

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

使用ajax / javascript轮询,每秒钟都会有一个setTimeout调用服务器文件,并查看已向服务器写入了多少数据。 This article应该有助于提供轮询的良好示例和描述。回调将根据文件大小设置进度。

第二种方法是使用uploadProgress ajaxSubmit选项。 This article将为如何设置提供一个很好的教程。

以下是代码示例:

<强> 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;
}

答案 1 :(得分:-2)

看看这个answer on 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>