這篇文章是這個分類下的第四篇隨筆了,之前可能對文件上傳還不是很清晰,寫到這篇,也就明白套路了。
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 的方法,保存文件到本地。
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);
