前端預覽input上傳的圖片
既然要實現在前端預覽上傳的圖片,我們需要先了解input 和 file型別
Input 標籤的file型別,提供了上傳檔案的功能,通過此型別,可以上傳檔案到伺服器。
input的file型別,在上傳檔案時,會返回一個File物件,這個物件會存在一個FileList數組裡邊。之所以存在數組裡邊,主要是方便實現多檔案上傳。File物件繼承自Blob物件,也就是說Blob物件的屬性和方法,File物件也可以使用,而File物件本身也有自己的屬性和方法。
下圖是瀏覽器打印出來的FileList :
各項代表的意思分別是:
- lastModified屬性,返回File物件引用檔案最後的修改時間。
- lastModifiedDate屬性,引用檔案最後修改時間的Date物件。
- name屬性,所引用檔案的名字。
- size屬性,返回檔案大小。
- webkitRelativePath屬性,相關的Path或URL。
- type屬性,返回檔案的多用途網際網路郵件擴充套件型別(MIME型別)。
- getAsBinary() 將檔案內容按照原始二進位制形式解析成字串並返回.
前端顯示上傳圖片有兩種方法:
上傳照片前 上傳照片後
HTML:
<div id="containner"> <input type="file" id="imgFile" onchange="previewFile()"><br> <img src="" height="200" alt="Image preview..."> </div>
JS:
1、通過window.URL.createObjectURL(blob)
blob 為Blob物件 或者 File物件
這個方法會根據傳入的引數建立一個指向該引數物件的URL. 這個URL的生命僅存在於它被建立的這個文件裡
function previewFile() { var preview = document.querySelector('img') var fileDom = document.querySelector('input[type=file]') // 獲取得到file 物件 var file = fileDom.files[0] // 限制上傳圖片的大小 if(file.size > 1024 * 1024 * 2) { alert('圖片大小不能超過 2MB!'); return false; } // 建立url var imgUrl = window.URL.createObjectURL(file) preview.setAttribute("src", imgUrl) // 更改img url 以後釋放 url preview.onload = function() { // console.log('圖片載入成功') URL.revokeObjectURL(imgUrl) } }
附註:
在每次呼叫 createObjectURL()
方法時,都會建立一個新的 URL 物件,即使你已經用相同的物件作為引數建立過。
所以當不再需要這些 URL 物件時,每個物件必須通過呼叫 URL.revokeObjectURL()
方法來釋放。瀏覽器會在文件退出的時候自動釋放它們,但是為了獲得最佳效能和記憶體使用狀況,你應該在安全的時機主動釋放掉它們。
2、通過FileReader.readAsDataURL(blob)
blob 為Blob物件 或者 File物件
讀取操作完成的時候,readyState 會變成已完成(DONE),並觸發 loadend 事件,同時 result 屬性將包含一個data:URL格式的字串(base64編碼)以表示所讀取檔案的內容,如圖(為擷取的一部分):
function previewFile() {
var preview = document.querySelector('img');
var fileDom = document.querySelector('input[type=file]')
var file = fileDom.files[0]
// 限制上傳圖片的大小
if(file.size > 1024 * 1024 * 2) {
alert('圖片大小不能超過 2MB!');
return false;
}
// 當前瀏覽器支援FileReader
if(window.FileReader) {
var reader = new FileReader()
reader.readAsDataURL(file)
reader.addEventListener("load", function () {
console.log('reader.result', reader.result)
preview.src = reader.result
}, false)
}else {
alert('Not supported by your browser!')
}
}
FileReader
FileReader 物件允許Web應用程式非同步讀取儲存在使用者計算機上的檔案(或原始資料緩衝區)的內容,使用 File 或 Blob 物件來指定要讀取的檔案或資料,即 FileReader.readAsDataURL(blob) 的 引數blob 為 File物件 或 Blob 物件。 同時也適用於window.URL.createObjectURL()
File物件:
- 可以是來自使用者在一個<input>元素上選擇檔案後返回的FileList物件
- 可以是來自拖放操作生成的 DataTransfer物件
- 可以是來自在一個HTMLCanvasElement上執行mozGetAsFile()方法後返回結果
blob物件(二進位制資料):
- 通過new Blob()建立的物件就是Blob物件(關於Blob物件 ,下一篇再寫)
- XMLHttpRequest裡,如果指定responseType為blob,那麼得到的返回值也是一個blob物件.
上面這兩種方式,都可以讓圖片在前端頁面顯示,但是如果需要將圖片的資料傳送給伺服器,FileReader.readAsDataURL 這種方式更好,可以將得到的資料作為data傳遞給伺服器。
3、如果拿到圖片的地址,可以通過獲取圖片的blob物件,然後再通過FileReader.readAsDataURL(blob)拿到圖片data
第一步 :傳送ajax請求去獲取url 的blob值
function getImageBlob(url){
const xhr = new XMLHttpRequest()
xhr.open("get", url, true)
// 設定responseType 的型別, 為arraybuffer、blob都可以
xhr.responseType = "blob"
return new Promise((resolve, reject) => {
xhr.onload = () => {
resolve(xhr.response)
}
xhr.onerror = () => reject()
xhr.send()
})
}
第二步: 獲取圖片資料
function getImageData(imgBlob) {
// imgBlob 是一個ArrayBuffer型別的物件或者Blob物件
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onloadend = () => resolve(reader.result)
reader.onerror = reject
// 設定轉換的URL的型別,通過Blob 建構函式的type 來設定讀取出來的資料的型別
reader.readAsDataURL(new Blob([img], { type: "image/jpeg" }))
});
}
第三步: 封裝
function urlToData(url) {
return getImageData(url).then((imageData) =>
getTypeOfImage(imageData)
)
}
最後通過 await urlToData(url) 就可以得到圖片的資料了