以往用到圖片上傳功能都是直接使用現成的外掛,今天把其中用到的知識點整理一下。
知識點字典
- input 標籤之 file 型別
- FileReader 物件:讀取檔案
- FileReader.readAsDataURL():將讀取的檔案轉換為 base64 編碼的字串
- FormData 物件
- 使用 axios 上傳
input 標籤之 file 型別
當設定 input 標籤 type 為 file 時,input 表現性狀為上傳檔案樣式
file-input 有如下屬性:
- accept
指定選擇檔案型別的範圍。預設為所有檔案型別
圖片為 accept="image/*"
檔案型別取值見MDN - capture
當檔案型別為圖片或視訊且在移動端時,此屬性才有意義。- capture = 'user' 呼叫前置攝像頭
- capture = 'environment' 呼叫後置攝像頭
- 不設定則為使用者自己選擇
- multiple
一個 Boolean 值,如果存在,則表示使用者可以選擇多個檔案 - files
返回一個 FileList,列出每個所選檔案物件。除非 multiple 指定了屬性,否則此列表只有一個成員。主要用於 JS 操作。
<!-- html -->
<input type="file" multiple id="imgLocal" accept="image/*" />
複製程式碼
// js
let inp = document.querySelector('#imgLocal')
inp.onchange = function(e) {
let fileList = document.querySelector('#imgLocal').files
console.log(fileList) //files
}
複製程式碼
FileReader 物件
我們用 FileReader 物件實現圖片預覽功能。
FileReader 物件允許 Web 應用程式非同步讀取儲存在使用者計算機上的檔案(或原始資料緩衝區)的內容,使用 File 或 Blob 物件指定要讀取的檔案或資料。
建構函式
new FileReader()
返回一個新構造的 FileReader。
屬性
- FileReader.readyState
表示 FileReader 狀態的數字,取值如下- 0:EMPTY/還沒有載入任何資料
- 1:LOADING/資料正在被載入
- 2:DONE/已完成全部的讀取請求
- FileReader.result
檔案的內容。該屬性僅在讀取操作完成後才有效。 - FileReader.error
事件及方法
我們主要是用 FileReader.onload 事件及 FileReader.readAsDataURL() 方法,其他見MDN
- FileReader.onload
處理 load 事件。該事件在讀取操作完成時觸發 - FileReader.readAsDataURL() 開始讀取指定的 Blob 中的內容。一旦完成,result 屬性中將包含一個 data: URL 格式的字串以表示所讀取檔案的內容。
//繼續使用上文的fileList
let file = fileList[0]
const fileReader = new FileReader()
fileReader.readAsDataURL(file) //讀取圖片
fileReader.addEventListener('load', function() {
// 讀取完成
let res = fileReader.result
// res是base64格式的圖片
})
複製程式碼
我們將 DOM 上 img 的 src 設為讀取的結果即可實現預覽功能。
FormData 物件
FormData 物件的使用:
- 用一些鍵值對來模擬一系列表單控制元件:即把 form 中所有表單元素的 name 與 value 組裝成 一個 queryString
- 非同步上傳二進位制檔案。
建構函式
new FormData()
返回一個新構造的 FormData。
方法
FormData 方法有很多。我們這裡只用了她的 append()方法
formData.append(name, value, filename)
- name:屬性名
- value:屬性值,在我們這裡則指 file 資料
- filename:當第二個引數為 file 或 blob 時,告訴伺服器的檔名。Blob 物件的預設檔名是“blob”。File 物件的預設檔名 是檔案的檔名。
// 繼續使用上文的file
const formDate = new FormData()
formDate.append('userPicture', file, '1.jpg')
複製程式碼
使用 axios 上傳
主要是設定 header 中的 Content-Type
直接上程式碼
//繼續使用上文的formDate
let config = {
headers: {
'Content-Type': 'multipart/form-data'
}
}
axios
.post('serverUrl', formDate, config)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
複製程式碼
axios 亦可 使用onUploadProgress監聽上傳進度,不再贅述。
其他
其他還有直接form表單提交檔案等方式,可能不太自由。諸位有興趣的可以看一下。