【问题标题】:showing download progress while downloading a file using PHP and jquery使用 PHP 和 jquery 下载文件时显示下载进度
【发布时间】:2014-01-10 02:41:59
【问题描述】:

我正在使用 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 显示下载进度。谢谢

【问题讨论】:

  • 你真的不能那样做。一旦浏览器开始下载文件,我相信您将无法跟踪它。你为什么要这样做?每个浏览器都有某种进度指示?
  • 这不是 jQuery,它是纯 javascript。
  • 嗨 php_nub_qq ,进度条是为了让所有用户在所有浏览器和用户点击下载的同一屏幕上都有统一的感觉,因为不同的浏览器在不同的地方有不同的下载进度条。
  • 嗨,L105。是的,这是纯 javascript,我认为 jquery 可以提供更好的解决方案,所以我保持 jquery 选项打开。
  • 嗨,Ajit,我的回答能否帮助您解决您的问题/您的问题解决了吗?

标签: php jquery ajax


【解决方案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;
}

【讨论】:

    【解决方案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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多