前端文件數據格式那些事兒
前言
在 Web 開發中,當我們處理文件時(創建,上傳,下載),經常會遇到二進制數據。另一個典型的應用場景是圖像處理。
在 JavaScript 中有很多種二進制數據格式,比如ArrayBuffer,Uint8Array,DataView,Blob,File 等等,不過 JavaScript 中的二進制數據是以非標準方式實現的。
下面我們來了解下這些數據格式及相互轉換。
本文涉及到File,Blob,TypedArray,data url(Base64),blob url等等。
File
首先,我們還是拿前文的例子來看,顯示用戶選擇的圖片。
我們創建一個頁面。提供選擇圖片功能。
- <!DOCTYPE html>
- <html>
- <head>
- <title>test</title>
- </head>
- <body>
- <input type="file" id="fileInput" name="選擇圖片"/>
- <div class="wrap-image">
- <canvas id="canvas"></canvas>
- </div>
- <script type="text/javascript">
- </script>
- </body>
- </html>
選擇圖片后,需要將圖片顯示到canvas中,我們在上面的script標簽中加入下面的代碼:
- const fileInput = document.getElementById('fileInput')
- const canvas = document.getElementById('canvas')
- fileInput.addEventListener('change', (e) => {
- let img = new Image
- const file = e.target.files[0]
- img.src = URL.createObjectURL(file)
- img.onload = () => {
- canvas.width = img.width
- canvas.height = img.height
- const context = canvas.getContext('2d')
- context.drawImage(img, 0, 0)
- }
- }, false)
選擇一張圖片后,change事件中獲取到選擇的文件e.target.files[0]:

File 對象是特殊類型的 Blob,可以用在任意的 Blob 類型的 context 中。
比如 FileReader, URL.createObjectURL(), createImageBitmap(), 及 XMLHttpRequest.send() 都能處理 Blob 和 File。
File 接口也繼承了 Blob 接口的屬性。上圖的Prototype展開可以看到繼承自Blob:

上面是最常見的file獲取方式————從<input type="file">中獲取。
- new File(fileParts, fileName, [options])
- fileParts —— Blob/BufferSource/String 類型值的數組
- fileName —— 文件名字符串
- options —— 可選對象
FileReader
FileReader 的用途是從 Blob(因此也從 File)對象中讀取數據。
它使用事件來傳遞數據,因為從磁盤讀取數據可能比較費時間。
可以讀取為3種格式:

比如將 Blob 讀取為 base64:
- const reader = new FileReader()
- reader.readAsDataURL(file) // 將 Blob 讀取為 base64
使用時選擇哪一種,要看如何使用數據。
讀取過程中有下列事件:
1、loadstart: 開始加載
2、progress: 在讀取過程中出現
3、load: 讀取完成,沒有 error
4、abort: 調用了 abort()取消操作
5、error: 出現 error
6、loadend: 讀取完成,無論成功還是失敗
使用最廣泛的是load和error,比如下面的例子:
- <input type="file" onchange="readFile(this)">
- <script>
- const readFile = (input) => {
- const file = input.files[0]
- const reader = new FileReader()
- reader.readAsText(file)
- reader.onload = () => {
- console.log(reader.result) // 結果
- }
- reader.onerror = () => {
- console.log(reader.error) // error
- }
- }
- </script>
不過大多數情況下,我們不需要讀取Blob,通過網絡發送一個File很容易,像 XMLHttpRequest 或 fetch 等 API 本身就接受 File 對象。或者用URL.createObjectURL(file) 創建一個短的 url,并將其賦給 或 。這樣,文件便可以下載文件或者將其呈現為圖像,作為 canvas 等的一部分。
Blob