使用File API 之FileReader 實現文件上傳前預覽

  對於基於瀏覽器的應用而言,訪問本地文件都是一件頭疼的事情,一般咱們能作的僅僅是使用<input type="file">標籤來上傳文件。實現過程是:選取文件的時候value 屬性保存了用戶指定的文件的名稱,表單被提交的時候,瀏覽器會向服務器發送選中的文件的內容而不單單是發送文件名。再獲取服務器返回的地址,而後作預覽。html

  可是若是有一天咱們要上傳一個圖片,傳了圖片後預覽想換另外一張圖片,就又得先上傳到服務器再預覽。在網絡比較慢的狀況下,這樣真的很折騰。瀏覽器

  因此咱們某些時候須要先預覽再上傳到服務器,特別是一些有剪切功能的需求,例如新浪微博的頭像更換。可是目前能作的只能是藉助插件開發或者使用flash,因爲不一樣瀏覽器的技術實現不盡相同,爲了讓程序可以支持多瀏覽器,咱們的程序就會變得十分複雜而難於維護。幸虧如今有了File API。服務器

  經過監聽change事件咱們可得知用戶選擇的文件,而且添加了一個files集合,集合中將包含file對象,每一個file對象對應着一個文件。而且都有如下只讀屬性name,size,type,lastModifiedDate.網絡

 

以<input type="file" name="file" id="postFile">爲例,監控onchange事打印它的file對象:異步

  函數

  由此咱們可得知用戶選取的文件格式,文件名以及文件大小等等的一些信息。所以咱們很容易就能爲所選取的文件做驗證判斷是否符合咱們定的一些要求。post

除此以外File API還提供了FileReader類型讀取文件中的數據。this

FileReader類型實現的事一種異步文件讀取機制,相似於XMLHttpRequest,可是它讀的是文件系統而不是遠程服務器。而且提供了幾種讀取方法:編碼

    readAsText(file,encoding):以純文本形式讀取文件,將讀取到的文本保存在result屬性中,第二個參數用於指定編碼類型,可選。url

    readAsDataURL(file):讀取文件以數據URL的形式保存在result屬性中。

    readAsBinaryString(file):讀取文件並將一個字符串保存在result屬性中。

    readAsArrayBuffer(file):讀取文件並將一個包含文件人容的ArrayBuffer保存在result屬性中

經過以上方法分別讀取同一張本地圖片,而且把保存在result屬性中的信息打印出來對好比下:

 

readAsText(file,encoding):

 

readAsDataURL(file):

 

  經過以上對比咱們發現這些讀取文件的方法爲靈活的處理文件數據提供了極大的方便。例如讀取圖像文件而且保存爲數據url,能夠作上傳前的預覽功能。

  因爲讀取的過程是異步的,因此FileReader裏面有幾個事件分別處理不一樣的狀況:progress(是否讀取了新數據)、erro(是否發生了錯誤)、load(是否已經讀完了整個文件)。

  因爲種種緣由沒法讀取文件就會觸發error事件,觸發error事件的時會有一個屬性code(錯誤碼)保存在FileReader的error屬性裏面的一個對象中。

 

使用FileReader作上傳預覽的例子:

HTML:

<label class="item_label">上傳照片:
	<span style="width: 100px; height: 100px;border:1px solid #ccc; display:inline-block"><img src="#" id="uploadPreview" style="width: 100%; height: 100%;"></span>
	<input type="file" name="file" id="postFile" style="width:74px;">
	<span id="error_text" style="display: none;">提示</span>
</label>

  

JavaScript:

    var _alertMsg = document.getElementById('error_text');
document.getElementById(
'postFile').onchange = function() {
    
var val = this.value;
//設定可上傳的格式     var upLoadType = '.jpg,.gif,.bmp,.png'; //從字符串中抽出最後一次出現.以後的字符,而且轉換成小寫     var fileExt = val.substr(val.lastIndexOf(".")).toLowerCase(); //查找後綴名是否符合條件,若是符合返回>=0,若是不符合則返回負數;     var result = upLoadType.indexOf(fileExt);         if (this.files.length === 0) { return; } //若是隻有一個文件則只須要訪問這個FileList對象中的第一個元素.     var oFile = this.files[0];           if (oFile.size / 1024 < 100) {         _alertMsg.innerHTML = "<font style='color:blue'>√</font>" _alertMsg.style.display = 'inline-block';     };     if (result < 0) { _alertMsg.innerHTML = "請輸入正確格式:" + upLoadType; _alertMsg.style.display = 'inline-block';     } else{ _alertMsg.innerHTML = "<font style='color:blue'>√</font>"; _alertMsg.style.display = 'inline-block';     };      var oFReader = new FileReader(); // 當圖像文件加載後,轉換成一個data:URL,傳遞到onload回調函數中     oFReader.readAsDataURL(oFile);     oFReader.onload = function (oFREvent) {         document.getElementById("uploadPreview").src = oFREvent.target.result;     }; };

 

  

效果以及返回的圖片URL:

相關文章
相關標籤/搜索