2016-09-20 38 views
5

Tôi đang cố gắng tải xuống tệp bằng Ajax và hiển thị thanh tiến trình tải xuống tùy chỉnh.Hiển thị thanh tiến trình để tải xuống tệp bằng XHR2/AJAX

Vấn đề là tôi không thể hiểu cách thực hiện. Tôi đã viết mã để ghi lại tiến trình nhưng không biết cách bắt đầu tải xuống.

LƯU Ý: Các tệp có nhiều loại khác nhau.

Xin cảm ơn trước.

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 và 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

How are you gửi tập tin mà bạn đã tải xuống để người sử dụng? –

+0

Nếu bạn hỏi tôi làm cách nào để tải xuống tệp, đó là những gì tôi muốn biết làm cách nào để tải xuống tệp. – Ayan

+0

Có vẻ như bạn đã hỏi cách hiển thị tiến trình, nhưng khi đọc lần hai, đây là phần bổ sung cho quá trình tải xuống. Câu trả lời đơn giản: không sử dụng ajax để tải xuống tệp, sử dụng trình duyệt. 'download' –

Trả lời

7

Nếu bạn muốn hiển thị cho người dùng một sự tiến bộ-bar của quá trình tải xuống - bạn phải thực hiện tải trong XMLHttpRequest . Một trong những vấn đề ở đây là nếu các tệp của bạn lớn - chúng sẽ được lưu trong bộ nhớ của trình duyệt trước khi trình duyệt ghi chúng vào đĩa (khi sử dụng các tệp tải xuống thông thường đang được lưu trực tiếp vào đĩa, tiết kiệm rất nhiều bộ nhớ trên các tệp lớn).

Một điều quan trọng cần lưu ý - để cho lengthComputable là đúng - máy chủ của bạn phải gửi tiêu đề Content-Length với kích thước của tệp.

Đây là đoạn mã 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> 

Và đây là một ví dụ cho mã php bạn có thể sử dụng:

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

Lưu ý rằng tôi đã thêm một giấc ngủ để mô phỏng một kết nối chậm để thử nghiệm trên máy chủ cục bộ.
Bạn nên loại bỏ này vào sản xuất :)

+0

Ví dụ hoàn hảo cho _force tải xuống bằng ajax_ – Viney

+0

@Novice, cảm ơn nhận xét đó :) – Dekel

Các vấn đề liên quan