2013-04-25 36 views
0

我正在創建拖放上傳器,而我正在使用base64將數據發送到使用隱藏字段的服務器。 (該文件將在稍後發送,而不會立即刪除)。使用拖放上傳文件不穩定

測試小圖像文件和文本文件的效果非常好,但是當我嘗試使用20MB的zip或2MB的WAV時,整體變得不穩定。谷歌瀏覽器崩潰或顯示一個空白的輸出框,Firefox掛起很長時間,最終顯示base64字符串。 IE實際上只工作一次,並顯示最快的字符串,但仍然有不可接受的等待時間。

是我的代碼效率低下還是別的嗎?

這裏是我的代碼:

<div id="drop_zone">Drop files here</div> 
<input name="filebox" type="text" id="filebox" size="300"> 
<output id="list"></output> 

<script> 
function handleFileSelect(evt) { 
evt.stopPropagation(); 
evt.preventDefault(); 

var filelist = evt.dataTransfer.files; // FileList object. 
file = filelist[0]; 
var reader = new FileReader() 
reader.onload = function(e) { 
document.getElementById('filebox').value = e.target.result; 
} 
reader.readAsDataURL(file) //readAsdataURL 
} 

function handleDragOver(evt) { 
evt.stopPropagation(); 
evt.preventDefault(); 
evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. 
} 


var dropZone = document.getElementById('drop_zone'); 
dropZone.addEventListener('dragover', handleDragOver, false); 
dropZone.addEventListener('drop', handleFileSelect, false); 
</script> 

這個測試頁面是活在:http://www.tabbicat.info/local/propellor/drop.html

+0

你是如何執行的base64編碼查看文件選擇方法是什麼?你使用本地的window.btoa或一些javascript製作的功能? FileReader()使用以下行輸出到它:reader.readAsDataURL(file)。 – Xotic750 2013-04-25 22:33:11

+0

我不完全理解這是如何工作的,因爲reader.onload函數是設置輸入框的內容? – joshkrz 2013-04-25 22:35:58

+0

將這些大文件中的一個放到html5rocks演示中時會發生什麼,該代碼來自何處?我在那裏放了一個23Mb的數據,它在幾秒鐘內就出現了。在你嘗試相同的鏈接,並在幾秒鐘內相同。 – Xotic750 2013-04-25 22:56:33

回答

0

好吧,我想你的活鏈接,同樣的demo,可用在html5rocks,兩者前後花了2秒爲23Mb文件。然後我嘗試在jsfiddle中創建精確的代碼,但由於某種原因,拖放操作不想運行。所以我使用了文件選擇器方法。再次,讀取文件花費了大約2秒。我能想到的是,您可能會遇到一些機器內存問題,例如缺少內存或某些內容,或者可能是HDD傳輸速度?或者,在瀏覽器中可能會出現一些拖放代碼的問題。 :/

無論如何,你可以在我的jsfiddle

#progress_bar { 
    margin: 10px 0; 
    padding: 3px; 
    border: 1px solid #000; 
    font-size: 14px; 
    clear: both; 
    opacity: 0; 
    -moz-transition: opacity 1s linear; 
    -o-transition: opacity 1s linear; 
    -webkit-transition: opacity 1s linear; 
} 
#progress_bar.loading { 
    opacity: 1.0; 
} 
#progress_bar .percent { 
    background-color: #99ccff; 
    height: auto; 
    width: 0; 
} 

<input type="file" id="files" name="file" /> 
<button onclick="abortRead();">Cancel read</button> 
<div id="progress_bar"> 
    <div class="percent">0%</div> 
</div> 

var reader; 
var progress = document.querySelector('.percent'); 

function abortRead() { 
    reader.abort(); 
} 

function errorHandler(evt) { 
    switch (evt.target.error.code) { 
     case evt.target.error.NOT_FOUND_ERR: 
      alert('File Not Found!'); 
      break; 
     case evt.target.error.NOT_READABLE_ERR: 
      alert('File is not readable'); 
      break; 
     case evt.target.error.ABORT_ERR: 
      break; // noop 
     default: 
      alert('An error occurred reading this file.'); 
    }; 
} 

function updateProgress(evt) { 
    // evt is an ProgressEvent. 
    if (evt.lengthComputable) { 
     var percentLoaded = Math.round((evt.loaded/evt.total) * 100); 
     // Increase the progress bar length. 
     if (percentLoaded < 100) { 
      progress.style.width = percentLoaded + '%'; 
      progress.textContent = percentLoaded + '%'; 
     } 
    } 
} 

function handleFileSelect(evt) { 
    // Reset progress indicator on new file selection. 
    progress.style.width = '0%'; 
    progress.textContent = '0%'; 

    reader = new FileReader(); 
    reader.onerror = errorHandler; 
    reader.onprogress = updateProgress; 
    reader.onabort = function (e) { 
     alert('File read cancelled'); 
    }; 
    reader.onloadstart = function (e) { 
     document.getElementById('progress_bar').className = 'loading'; 
    }; 
    reader.onload = function (e) { 
     // Ensure that the progress bar displays 100% at the end. 
     progress.style.width = '100%'; 
     progress.textContent = '100%'; 
     setTimeout("document.getElementById('progress_bar').className='';", 2000); 
    } 

    // Read in the image file as a binary string. 
    reader.readAsDataURL(evt.target.files[0]); 
} 

document.getElementById('files').addEventListener('change', handleFileSelect, false); 
+0

我嘗試了我在測試服務器上使用的相同文件,並且在jsfiddle上也花了大約兩秒鐘的時間。我注意到,該代碼不是從文件中獲取base64字符串。也許這就是問題所在? – joshkrz 2013-04-25 23:13:00

+0

我將其更改爲'readAsDataURL'並更新了jsfiddle,但速度並沒有明顯不同。 – Xotic750 2013-04-25 23:27:11

+0

下來的選民是否會關心爲什麼留下評論,並給我一個機會解決對這篇文章毫無幫助的一切? – Xotic750 2013-04-26 13:50:57