showing download progress while downloading a file using PHP and jquery

19,782

Two possible methods include using either polling or the uploadProgress ajaxSubmit option.

Using ajax / javascript polling, you would have a setTimeout every second that calls a server file and sees how much data has been written to the server. This article should help provide a good example and description of polling. The callback would set the progress based on the file size.

The second method is using the uploadProgress ajaxSubmit option. This article will give a good tutorial for how to set this up.

The following is a code example:

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;
}
Share:
19,782

Related videos on Youtube

Ajit Kumar
Author by

Ajit Kumar

Updated on September 17, 2022

Comments

  • Ajit Kumar
    Ajit Kumar over 1 year

    I am developing a download manager using PHP and jquery.

    Requested a script that will download a file and also show the download progress.

    I tried the following, but it not works

    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);
    }
    ?>
    

    Looking for a suggestion, how we can download a file and also show download progress using PHP and javascript. Thanks