FileReader
FileReader
對象允許 Web 應用程式異步讀取存儲在使用者計算機上的檔案(或原始資料緩沖區)的内容,使用
File
或
Blob
對象指定要讀取的檔案或資料。
其中 File 對象可以是來自使用者在一個
<input>
元素上選擇檔案後傳回的
FileList
對象,也可以來自拖放操作生成的
DataTransfer
對象,還可以是來自在一個
HTMLCanvasElement
上執行
mozGetAsFile()
方法後傳回結果。
重要提示:
FileReader
僅用于以安全的方式從使用者(遠端)系統讀取檔案内容 它不能用于從檔案系統中按路徑名簡單地讀取檔案。要在
JavaScript
中按路徑名讀取檔案,應使用标準
Ajax
解決方案進行伺服器端檔案讀取,如果讀取跨域,則使用
CORS
權限。
構造函數
-
傳回一個新構造的FileReader()
。FileReader
屬性
-
FileReader.error
隻讀
一個
,表示在讀取檔案時發生的錯誤 。DOMException
-
FileReader.readyState
隻讀
表示
狀态的數字。取值如下:FileReader
常量名 | 值 | 描述 |
| | 還沒有加載任何資料。 |
| | 資料正在被加載。 |
| | 已完成全部的讀取請求。 |
-
FileReader.result
隻讀
檔案的内容。該屬性僅在讀取操作完成後才有效,資料的格式取決于使用哪個方法來啟動讀取操作。
事件處理
-
處理FileReader.onabort
事件。該事件在讀取操作被中斷時觸發。abort (en-US)
-
處理FileReader.onerror
事件。該事件在讀取操作發生錯誤時觸發。error (en-US)
-
處理FileReader.onload
事件。該事件在讀取操作完成時觸發。load (en-US)
-
處理FileReader.onloadstart
事件。該事件在讀取操作開始時觸發。loadstart (en-US)
-
處理FileReader.onloadend
事件。該事件在讀取操作結束時(要麼成功,要麼失敗)觸發。loadend (en-US)
-
處理FileReader.onprogress
事件。該事件在讀取progress (en-US)
時觸發。Blob
備注: 因為
FileReader
繼承自
EventTarget
,是以所有這些事件也可以通過
addEventListener
方法使用。
方法
-
中止讀取操作。在傳回時,FileReader.abort()
屬性為readyState
。DONE
-
開始讀取指定的FileReader.readAsArrayBuffer()
中的内容,一旦完成,result 屬性中儲存的将是被讀取檔案的Blob
資料對象。ArrayBuffer
-
FileReader.readAsBinaryString()
非标準
開始讀取指定的
中的内容。一旦完成,Blob
屬性中将包含所讀取檔案的原始二進制資料。result
-
FileReader.readAsDataURL()
開始讀取指定的
中的内容。一旦完成,Blob
屬性中将包含一個result
URL 格式的 Base64 字元串以表示所讀取檔案的内容。data:
-
開始讀取指定的FileReader.readAsText()
中的内容。一旦完成,Blob
屬性中将包含一個字元串以表示所讀取的檔案内容。result
封裝讀取檔案方法
const fileToDataURL = (file: Blob): Promise<any> => {
return new Promise((resolve) => {
const reader = new FileReader()
reader.onloadend = (e) => resolve((e.target as FileReader).result)
reader.readAsDataURL(file)
})
}
然後将檔案流轉成圖檔.
Image()
**
Image()
**函數将會建立一個新的
HTMLImageElement
執行個體。
它的功能等價于
document.createElement('img')
文法
Image(width, height)
參數
-
width
圖檔的寬度 (即
屬性).width
-
height
圖檔的高度 (即
屬性).height
封裝将檔案流轉成圖檔方法
const dataURLToImage = (dataURL: string): Promise<HTMLImageElement> => {
return new Promise((resolve) => {
const img = new Image()
img.onload = () => resolve(img)
img.src = dataURL
})
}
關于canvas封裝
const canvastoFile = (canvas: HTMLCanvasElement, type: string, quality: number): Promise<Blob | null> => {
return new Promise((resolve) => canvas.toBlob((blob) => resolve(blob), type, quality))
}
最後就是整合成一個異步的圖檔壓縮方法
const fileToDataURL = (file: Blob): Promise<any> => {
return new Promise((resolve) => {
const reader = new FileReader()
reader.onloadend = (e) => resolve((e.target as FileReader).result)
reader.readAsDataURL(file)
})
}
const dataURLToImage = (dataURL: string): Promise<HTMLImageElement> => {
return new Promise((resolve) => {
const img = new Image()
img.onload = () => resolve(img)
img.src = dataURL
})
}
const canvastoFile = (canvas: HTMLCanvasElement, type: string, quality: number): Promise<Blob | null> => {
return new Promise((resolve) => canvas.toBlob((blob) => resolve(blob), type, quality))
}
/**
* 圖檔壓縮方法
* @param {Object} file 圖檔檔案
* @param {String} type 想壓縮成的檔案類型
* @param {Nubmber} quality 壓縮品質參數
* @returns 壓縮後的新圖檔
*/
export const compressionFile = async(file, type = 'image/jpeg', quality = 0.5) => {
const fileName = file.name
const canvas = document.createElement('canvas')
const context = canvas.getContext('2d') as CanvasRenderingContext2D
const base64 = await fileToDataURL(file)
const img = await dataURLToImage(base64)
canvas.width = img.width
canvas.height = img.height
context.clearRect(0, 0, img.width, img.height)
context.drawImage(img, 0, 0, img.width, img.height)
const blob = (await canvastoFile(canvas, type, quality)) as Blob // quality:0.5可根據實際情況計算
const newFile = await new File([blob], fileName, {
type: type
})
return newFile
}