今天在寫圖片上傳功能時,想要在前端檢測用戶選中的文件是否為圖片的功能,首先當然是在 input 里面設置 accept="image/*" 啦,但是這樣也不能保證上傳的一定是圖片,因為用戶可以在選擇文件框中修改展示的文件后綴,令其可以選中所有類型的文件。於是,便需要在 js 中進行判斷。
我先去谷歌了一下其他人的方法,通常大家有兩種判斷方法,其一是獲取上傳文件的 type 屬性值,但是這並不能防范用戶修改文件后綴名為圖片后綴后上傳文件,另一種方法是判定文件的 MIME TYPE,該方法調用了 readAsArrayBuffer 方法,經過幾步操作后獲取到了文件類型簽名,於是便可比對該簽名與對應允許上傳的圖片類型簽名是否吻合,如吻合,便可上傳,詳情點擊使用 JavaScript 檢測文件 MIME TYPE。
我覺得第一種防了和沒防也沒啥區別,第二種有點繁瑣,便先去測試一下我先前寫的頭像上傳功能,看其能不能加載錯誤的文件。一試,哇哦,加載大失敗,還沒報錯,有意思。查看了一下代碼,加入了幾個 console 進行了測試,發現關鍵在於 Image 對象。
當使用 Image 對象時,我們通常會先對其 src 屬性進行賦值,之后監聽 onload 事件,並在其中編寫或傳遞函數來回調。當我們傳入非圖片文件時,圖片不會調用 onload 事件,於是非圖片文件便不會上傳啦。
這是代碼:
HTML
<input type="file" accept="image/*" multiple="multiple" @change="uploadChange" />
JavaScript(該方法在 Vue 的 methods 方法中)
uploadChange(event) { const target = event.target; const files = target.files; for (let file of files) { let reader = new FileReader(); reader.onload = e => { let img = new Image(); img.src = e.target.result; img.onload = () => { // do something }; }; // 用於將Blob對象轉換成base64編碼 reader.readAsDataURL(file); } }
