問題描述

我立即創建一個 iframe,並將 URL 設置為一個下載二進制文件 (xls,doc …) 的頁面。當文件正在下載時,我會顯示一個動畫。什麼時候沒有,我隱藏它。

問題是,Chrome 不知道文件何時完全下載,即 iframe 完全加載。我使用 iframe 屬性 readyState 來檢查 iframe 的狀態:

var iframe = document.createElement("iframe");
iframe.style.visibility = "hidden";
// I start a progress animation
window.setTimeout(showProgressAnimation, 1000);
// I start the file download
iframe.src ='GetFile.aspx?file=' + fileName;
document.body.appendChild(iframe);


function showProgressAnimation() {
   if (iframe.readyState == "complete" || iframe.readyState == "interactive") {
      // I stop the animation and show the page
      animation.style.display = 'none';
      progressBar.hide();
      $('#page').show();
   }
   else {
      // Chrome is always getting into this line
      window.setTimeout(showProgressAnimation, 1000);
   }
}

所以結果是一個無限循環。

我已經嘗試了以下內容,它可以在 Firefox 和 Chrome 中運行,但是當內容是二進制文件時卻不行:

if ($.browser.mozilla || $.browser.webkit ) {
    iframe.onload = function showProgressAnimation() {
        animation.style.display = 'none';
        progressBar.hide();
        $('#page').show();
    }
}
// IE
else{
     window.setTimeout(showProgressAnimation, 1000);
}

最佳解決辦法

您可以使用 onload 來表示 iframe 的負載

這裏是一個簡單的例子,工作

var iframe = document.createElement("iframe");
iframe.style.display = "none";
// this function will called when the iframe loaded
iframe.onload = function (){
  iframe.style.display = "block";
  alert("loaded");
};
// set the src last.
iframe.src ='http://www.test.com';

// add it to the page.
document.getElementById("one").appendChild(iframe);

測試在這裏:http://jsfiddle.net/48MQW/5/最後加載 srchttp://jsfiddle.net/48MQW/24/

次佳解決辦法

請嘗試這個 – 你真的是混合 dom 和 jQuery 從一行到另一行

var tId;

function stopAnim() {
    // I stop the animation and show the page
    animation.hide();
    progressBar.hide();
    $('#page').show();
    clearInterval(tId);
}
var iframe = $("<iframe />");
iframe.css("visibility","hidden");

iframe.on("readystatechange",function() {
 if (this.readyState == "complete" || this.readyState == "interactive") {
   stopAnim();
 }
});
iframe.on("load",function() { // can possibly be deleted
 if (tId) {
   stopAnim();
 }
});

iframe.attr("src","GetFile.aspx?file=" + fileName);
$("body").append(iframe);
tId = setInterval(function() {
  // update progress here
}, 1000); //

第三種解決辦法

可下載的文件內容不會觸發 readystatechange 事件處理程序或 onload 事件處理程序。這個 couse 你可以在服務器端設置一個 cookie 文件內容,客户端定期檢查這個 cookie 。例如:

服務器

response.cookie('fileDownloaded','true');
response.header('attachment','your-file-name.any');
//...write bytes to response...

客户

var checker = setInterval(()=>{
    if(document.cookie.indexOf('fileDownloaded')>-1){
        alert('done');
        clearInterval(checker);
    }
},100);

當然,您可以使用框架來正確檢查 cookie 值,這只是一個 poc,而不是一個安全的 cookie 解析器。

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。