第四篇:一文讀懂前端上傳下載(前端讀取文件 | FileReader 對象 | 前端保存文件到本地 | Blob 對象 | URL 對象)


這篇文章是這個分類下的第四篇隨筆了,之前可能對文件上傳還不是很清晰,寫到這篇,也就明白套路了。

ps:這就是寫博客的好處。

前端讀取文件

第一步:定義一個input標簽type="file"

覺得 <input/> 樣式難看又難改的,請看一下這個分類下的第三篇隨筆

如果需要對讀取到的文本內容進行修改,可以用 <textarea></textarea> 多行文本域,簡單模擬一個前端代碼編輯器。推薦使用 codemirror2(代碼編輯器)

<input
  type="file"
  onChange={(ev) => getFiles(ev.target.files)}
  accept=".yaml" // 規定可以讀取的文件類型(不寫或等於""時,為全部類型。可以連寫->".xlsx, .txt, .yaml")
// multiple="multiple" // 可以接受多個值得上傳 字段
/>
<span id="textInner" >
  // 留一個元素,可以將獲取到的文件信息展示出來,注意不要忘了設置該元素的樣式(寬、高、、、)
</span>

第二步:定義一個 getFiles 的方法,讀取上傳的文件。

getFiles = (files) => {
  const textInner = document.getElementById("textInner"); // 獲取一個標簽,把讀取的內容插進去
  if (files.length) {
    const file = files[0];
    const reader = new FileReader(); // new一個FileReader實例
    if (/text+/.test(file.type)) { // 判斷文件類型,是不是text類型
      reader.readAsText(file);
      reader.onload = function () {
        textInner.innerText = this.result
      }
    } else if (/image+/.test(file.type)) { // 判斷文件是不是imgage類型
      reader.readAsDataURL(file);
      reader.onload = function () {
        textInner.innerHTML = '<img src="' + this.result + '"/>'
      }
    } else { // 其它類型
      reader.readAsText(file);
      reader.onload = function () {
        // this === reader 非箭頭函數,誰調用this指向誰
        console.log(this.result) // 文件內容
      }
    }
  }
}

到這里,讀取文件就結束了,下面來了解一下 html5 的 FileReader 對象及其屬性

 


 

FileReader 對象

FileReader提供了如下方法:

/*
reader.readAsText(file, [encoding]); // 將文件讀取為文本,其中第二個參數是文本的編碼方式,不寫默認值為 UTF-8
reader.readAsDataURL(file); // 讀取文件內容,結果用data:url的字符串形式表示(常用於媒體文件:圖片、音頻、視頻)
reader.readAsArrayBuffer(file); // 按字節讀取文件內容,結果用ArrayBuffer對象表示
reader.readAsBinaryString(file); // 按字節讀取文件內容,結果為文件的二進制串
reader.abort() // 終止讀取文件
*/

FileReader事件:

/*
onabort     當讀取操作被終止時調用
onerror     當讀取操作發生錯誤時調用
onload      當讀取操作成功完成時調用
onloadend   當讀取操作完成時調用,無論成功失敗
onloadstart 當讀取操作開始時調用
onprogress  當讀取數據過程中周期性調用
*/

文件一旦開始讀取,無論成功或失敗,實例的 result 屬性都會被填充。如果讀取失敗,則 result 的值為 null ,否則即是讀取的結果。

如果讀取文件過大的話fileReader允許分段讀取文件;

var blob_file;
if(file.webkitSlice) {  //chrome
        blob_file= file.webkitSlice(start, end + 1, 'text/plain;charset=UTF-8');
} else if(file.mozSlice) { //Firefox
        blob_file= file.mozSlice(start, end + 1, 'text/plain;charset=UTF-8');
}

順便嘮叨一下base64編碼的優缺點:

優點:

  1.減少了http請求。

  2.沒有跨域的問題。

  3.直接放在路徑里不需要清理緩存。

缺點:

  1.IE6/7不支持(不過這個問題不大);

  2.base64本質上是將圖片以二進制的字母展示,字符量過大無形中增加了css/html文件的大小;

 


 

前端文件到本地

第一步:隨便來個元素,綁定點擊事件

<button onClick={() => loadFile(file.name, value)}>保存到本地</button>

第二步:定義一個 loadFile 的方法,保存文件到本地。

const loadFile = (fileName = "新建yaml文檔.yaml", content) => { // 前端自動生成下載文件
   // content = reader.result 為文件的內容,也可以是修改后的內容。
  const aLink = document.createElement('a'); // 可以是任何能放置 url 的標簽,比如 <img src=""/> <a href=""/>
  const blob = new Blob([content], {  // content: 文件內容
    type: ""  //type: file.type, 當值為空字符串時,下載的文件類型以文件名的尾綴為准。
  });
  aLink.download = fileName;
  aLink.href = URL.createObjectURL(blob);
  aLink.click();
  URL.revokeObjectURL(blob);
  aLink.remove();
}

 


 

Blob 對象

概念:
Blob(Binary Large Object)對象代表了一段二進制數據,提供了一系列操作接口。其他操作二進制數據的 API(比如 File 對象),都是建立在 Blob 對象基礎上的,繼承了它的屬性和方法。

兩種使用方式:
生成 Blob 對象有兩種方法:一種是使用 Blob 構造函數,另一種是對現有的 Blob 對象使用 slice 方法切出一部分。

(1)Blob 構造函數,接受兩個參數。第一個參數是一個包含實際數據的數組,第二個參數是數據的類型,這兩個參數都不是必需的。

var a = ["hello", "world"];
var myBlob = new Blob(a, { "type" : "text/xml" });
console.log(myBlob);

(2)Blob 對象的 slice 方法,將二進制數據按照字節分塊,返回一個新的 Blob 對象。

var a = ["hello", "world"];
var myBlob = new Blob(a, { "type" : "text/xml" });
var newBlob = myBlob.slice(0, 5);
console.log(newBlob);

Blob 對象有兩個只讀屬性:

size:二進制數據的大小,單位為字節。(文件上傳時可以在前端判斷文件大小是否合適)
type:二進制數據的 MIME 類型,全部為小寫,如果類型未知,則該值為空字符串。(文件上傳時可以在前端判斷文件類型是否合適)

 


 

URL 對象

調用 URL 對象的 createObjectURL 方法,傳入一個 File 對象或者 Blob 對象,能生成一個鏈接,聽起來好像很吊的樣子。

var objecturl =  window.URL.createObjectURL(blob);

上面的代碼會對二進制數據生成一個 URL,這個 URL 可以放置於任何通常可以放置 URL 的地方,比如 img 標簽的 src 屬性。需要注意的是,即使是同樣的二進制數據,每調用一次 URL.createObjectURL 方法,就會得到一個不一樣的 URL。

這個 URL 的存在時間,等同於網頁的存在時間,一旦網頁刷新或卸載,這個 URL 就失效。(File 和 Blob 又何嘗不是這樣呢)除此之外,也可以手動調用 URL.revokeObjectURL 方法,使 URL 失效。

window.URL.revokeObjectURL(objectURL);
var blob = new Blob(["Hello hanzichi"]);
var a = document.createElement("a");
a.href = window.URL.createObjectURL(blob);
a.download = "a.txt";
a.textContent = "Download";
document.body.appendChild(a);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM