2016-09-20 101 views
5

我试图使用Ajax下载文件并显示自定义下载进度条。显示使用XHR2/AJAX下载文件的进度条

问题是我不明白该怎么做。我编写了代码来记录进度,但不知道如何启动下载。

注意:这些文件是不同的类型。

在此先感谢。

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和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) . '&nbsp; &#149; &nbsp;' . 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> 
+0

你怎么送你下载到用户的文件吗? –

+0

如果你问我如何下载文件,那么这就是我想知道我应该如何下载文件。 – Ayan

+0

它看起来像你问如何显示进度,但在第二次阅读,这是一个额外的下载。简单的答案:不要使用ajax来下载文件,使用浏览器。 'download' –

回答

7

如果你想显示用户下载过程的进度条 - 你必须做的XMLHttpRequest内下载。其中一个问题是,如果文件很大 - 在浏览器将它们写入磁盘之前,它们将被保存在浏览器的内存中(当使用常规下载文件直接保存到磁盘时在大文件上节省大量内存)。

另一个重要的事情要注意 - 为了使lengthComputable成立,您的服务器必须发送文件大小为Content-Length的标头。

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

这里是PHP代码的例子,你可以使用:

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

注意,我添加了一个睡眠模拟连接速度慢在本地主机上进行测试。
你应该删除此生产:)

+0

_force下载使用ajax_的完美示例 – Viney

+0

@Novice,感谢您的评论:) – Dekel