js前端上傳文件縮略圖技巧示例詳解
引言
通常情況下,前端提交給服務器的數據格式為JSON格式,但很多時候用戶想上傳自己的頭像、視頻等,這些非文本數據的時候,就不能直接以JSON格式上傳到後端瞭。
當我們要獲取用戶上傳的文件,可以使用input表單項,將type屬性值設置為“file”。
<form action=""> <input type="file" name="file"> </form>
同時,我們為表單項綁定change事件,當用戶上傳文件時,我們就可以在事件對象中獲取到用戶上傳的文件。
<script> const inp = document.querySelector("input") inp.onchange = function(e) { console.log(e.target.files); } </script>
但需要註意的是 e.target.files
是一個類數組(FileList),會將你上傳的多個文件都存儲在這個數組中,而這個例子中我們隻上傳一個文件,所以我們用 e.target.files[0]
將這個文件對象取出來。(若想上傳多個文件,可以在input標簽中增加multiple屬性)。
文件對象簡介
在學習上傳文件前,我們先簡單瞭解四個與文件相關的內置對象。
Blob
Blob是一個存儲二進制的對象,實際上很少直接使用這個對象。
- size 屬性,返回Blob對象的字節數,即文件的大小。
const input = document.getElementById('input'); const output = document.getElementById('output'); input.addEventListener('change', (e) => { output.innerText = `文件的大小為${e.target.files[0].size}`; });
- slice() 方法,對Blob對象進行切片,返回新的Blob對象。
- 可以用這個方法實現大文件切片上傳。
var blob = new Blob().slice([start [, end [, contentType]]]}; /* - start 開始位置的下標 - end 結束位置的下標 - contentType 給新的Blob賦予一個新的文檔類型。這將會把它的 type 屬性設為被傳入的值。它的默認值是一個空的字符串 */
File
- 通常情況下, File 對象是來自用戶在一個
<input>
元素上選擇文件後返回的 FileList 對象,也可以是來自由拖放操作生成的 DataTransfer 對象。 - file 對象是Blob的一個子類,因此file對象可以直接使用Blob中的方法和屬性。
const input = document.getElementById('input'); input.addEventListener('change', (e) => { let file = e.target.files[0] if(file.size > 4 * 1024 * 1024 || file.type != "image/jpeg"){ alert("文件不得大於4M,且圖片格式要為jpg格式。") } });
FileReader
- 異步讀取存儲在用戶計算機上的文件(或原始數據緩沖區)的內容,使用 File 或 Blob 對象指定要讀取的文件或數據。
var fr = new FileReader();
- readAsDataURL(),讀取指定的 Blob 或 File 對象。讀取操作完成的時候,readyState 會變成已完成DONE,並觸發 loadend 事件,同時 result 屬性將包含一個data:URL 格式的字符串(base64 編碼)以表示所讀取文件的內容。
fr.readAsDataURL(blob) /* - blob,被讀取的 blob 或 file對象 */
- readAsText(),將 Blob 或者 File 對象根據特殊的編碼格式轉化為內容 (字符串形式)。
fr.readAsDataURL(blob) /* - blob,被讀取的 blob 或 file對象 */
註意,以上兩個方法都是異步的,也就是說,隻有當執行完成後才能夠查看到結果,如果直接查看是無結果的,並返回 undefined。我們需要為fr掛載load或loadend事件,在事件回調中使用result
屬性才能獲取結果。
<input type="file" onchange="previewFile()"> <img src="" height="200"> <script> function previewFile(e) { var img = document.querySelector('img'); let file = e.target.files[0]; let fr = new FileReader(); reader.readAsDataURL(file); fr.addEventListener("load", function () { img.src = fr.result; }); } </script>
FormData
- 提供瞭一種表示表單數據的鍵值對 key/value 的構造方式。
- 在
<form>
標簽中,我們直接點擊提交按鈕,瀏覽器會以默認以x-www-form-urlencoded的數據格式向服務器提交數據。 - 當我們為
form
標簽設置enctype屬性時,可以設置發送的數據格式。
<!-- application/x-www-form-urlencoded 在發送前編碼所有字符(默認) multipart/form-data 不對字符編碼。在使用包含文件上傳控件的表單時,必須使用該值 text/plain 空格轉換為 "+" 加號,但不對特殊字符編碼。 --> <form action="/upload" enctype="multipart/form-data" method="post"> <input type="text" name="username"> <input type="password" name="password"> <input type="file" name="file"> <input type="submit"> </form>
在上面的例子中,瀏覽器會以formdata的數據格式向服務器發送表單數據,但我們使用框架來編寫業務時,我們不會直接使用表單提交數據,通常都是將表單中的數據提取出來,手動構建出相應的數據格式,再用aixos發送給服務器,所以我們需要主動使用FormData對象封裝file對象
- append() 方法,向 FormData 中添加新的屬性值,FormData 對應的屬性值存在也不會覆蓋原值,而是新增一個值,如果屬性不存在則新增一項屬性值。
function previewFile(e) { const formdata = new FormData() formData.append("userAvatar", e.target.files[0]); } /* 第一個值為文件名稱,第二個值為要傳送的文件對象/字符串 */
文件對象之間的關系
- 由上圖可以看出,當我們通過input標簽上傳文件時,我們可以得到一個file對象,file對象與blob對象可以互相轉換,但要將文件對象上傳給服務器則是不允許的,因為後端無法識別這種對象,因此我們需要將文件對象包裝成formdata對象,或者轉換為base64等文本格式再傳給後端。
function previewFile(e) { let file = e.target.files[0]; let formdata = new FormData() formdata.append("userAva", file) // 註意,若要實現大文件分片上傳時,同一個文件分片的文件名要相同,方便後端拼接 axios.post("http://localhost/...", { data: formdata }).then( res => { console.log(res) ) }
縮略圖的實現
我們通過input標簽上傳圖片後,用戶無法查看所提交的圖片。
因此為瞭提高用戶體驗,我們在用戶提交圖片後,將圖片在頁面中顯示出來。
<form action=""> <input type="file" name="file"><br/> <img src="" alt=""> </form> <script> const inp = document.querySelector("input") const img = document.querySelector("img") const fr = new FileReader() inp.onchange = function(e) { let file = e.target.files[0] fr.readAsDataURL(file) } fr.onload = function() { img.src = fr.result } </script>
未提交前
提交後
總結
- 前端上傳文件時需要使用FormData對象對文件進行包裝後才能傳給服務器。
- 獲取用戶上傳的圖片後,使用FileReader對象中提供的readAsDataUrl()方法,將圖片轉化為base64格式,再將base64編碼讓img標簽加載,實現縮略圖的效果。
以上就是js前端上傳文件縮略圖技巧示例詳解的詳細內容,更多關於js前端上傳文件縮略圖的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- JS中URL.createObjectURL使用示例講解
- JS使用base64格式上傳文件
- Blob對象實現文件上傳下載示例詳解
- JavaScript中的FileReader示例詳解
- 淺談JS的二進制傢族