JS獲取本地文件并進(jìn)行網(wǎng)絡(luò)傳輸?shù)拇a詳解
獲取文件
在web中如想要獲取用戶計(jì)算機(jī)上的文件我們通常會(huì)用到的方法是通過一個(gè)表單元素<input type="file">
操作用戶選擇的文件。
我們可以在js中通過監(jiān)聽該元素的change
事件獲取到文件信息,通常文件會(huì)被存放在該元素的files
集合中,例如:
<input type="file"> <script> const files = document.querySelector('input'); files.addEventListener('change',(e)=>{ console.log(e.target.files); }) </script>
File對(duì)象
File
對(duì)象中主要有以下幾個(gè)常用的屬性,并且都是只讀屬性。
name
:在系統(tǒng)中的文件名。size
:文件大?。▎挝粸樽止?jié))。type
:文件的MIME類型。lastModified
:文件最后修改時(shí)間。
通過我們可以通過這些文件的基本信息對(duì)選擇的文件進(jìn)行基本的過濾或是驗(yàn)證,例如:
function validateFile(file){ const maxSize = 1 * 1024 * 1024; const types = ['.jpg','.jpeg','.png','.bmp','.webp','.gif']; const fileName = file.name.toLowerCase(); if(file.size > maxSize){ alert('文件過大!'); return false; } if(!types.some((item)=>fileName.endsWith(item))){ alert('文件類型不匹配!'); return false; } return true; } files.addEventListener('change',(e)=>{ if(!validateFile(e.target.files[0])){ e.target.value = ''; return; } // 后續(xù)操作... })
在以上代碼中我們通過一個(gè)函數(shù)來判斷我們選擇的一個(gè)文件是否符合要求以進(jìn)行下一步操作,主要通過file
對(duì)象上的屬性判斷了文件的大小和類型是否符合要求,通過不同函數(shù)我們可以過濾掉不符合我們預(yù)期的文件。
在File
對(duì)象上是不包含文件的內(nèi)容信息的,但通常情況下我們獲取到File
對(duì)象上文件信息的目的是要讀取到真實(shí)的文件數(shù)據(jù)信息,這時(shí)候就要借助另一個(gè)API:FileReader
。
FileReader
FileReader
是js中提供用于讀取文件數(shù)據(jù)的API,它可以從本地文件系統(tǒng)中讀取文件數(shù)據(jù),其讀取過程是異步進(jìn)行的。
FileReader對(duì)象的常用方法:
readAsDataURL
:這個(gè)方法可以讀取文件并將其內(nèi)容數(shù)據(jù)轉(zhuǎn)化為數(shù)據(jù)URL,結(jié)果存儲(chǔ)到FileReader
實(shí)例的result
屬性上。readAsText
:讀取文件的純文本內(nèi)容,同樣結(jié)果存儲(chǔ)到FileReader
實(shí)例的result
屬性上。readAsBinaryString
:讀取文件的二進(jìn)制信息,同樣結(jié)果存儲(chǔ)到FileReader
實(shí)例的result
屬性上。
由于讀取文件的過程是異步的,所以我們主要是通過FileReader
提供的監(jiān)聽事件來獲取文件的信息,常用的事件有三個(gè):
load
:文件成功加載后觸發(fā),此時(shí)可以通過result
屬性獲取到文件信息。progress
:文件讀取進(jìn)度信息,每50ms
觸發(fā)一次,屬性與XHR
中的類似。error
:文件讀取出錯(cuò)時(shí)觸發(fā),若error
事件觸發(fā)則load
事件將不會(huì)觸發(fā)。在error
觸發(fā)后可以通過實(shí)例上的error
屬性獲取到錯(cuò)誤信息,其包含一個(gè)信息碼,代表的意思分別是:1(未找到文件)、2(安全錯(cuò)誤)、3(讀取被中斷)、4(文件不可讀)、5(編碼錯(cuò)誤)。
假設(shè)我們需要讀取一張圖片然后顯示到頁(yè)面中我們就可以進(jìn)行如下操作:
const files = document.querySelector('input'); const img = document.querySelector('img'); files.addEventListener('change',(e)=>{ let file = e.target.files[0]; // 驗(yàn)證文件基本信息 if(!validateFile(file)){ e.target.value = ''; return; } let reader = new FileReader(); reader.readAsDataURL(file); // 讀出文件信息并轉(zhuǎn)化為URL reader.addEventListener('load',(e)=>{ console.log('文件加載完成'); img.src = e.target.result; // 將URL賦予img元素,此時(shí)e.target為reader }) })
文件上傳
當(dāng)我們?cè)诳蛻舳双@取到了文件后我們又將如何將文件上傳呢?將文件上傳至服務(wù)器,這必然就涉及到了網(wǎng)絡(luò)通信,而在js中進(jìn)行網(wǎng)絡(luò)通信那自然就會(huì)用到ajax了。
利用XHR進(jìn)行文件上傳
進(jìn)行網(wǎng)絡(luò)通信,我們只要想到組成一個(gè)http
報(bào)文就自然而然的指定該如何編寫代碼了,http
請(qǐng)求主要包含了請(qǐng)求行、請(qǐng)求頭、請(qǐng)求體三部分信息。例如我需要實(shí)現(xiàn)以下http
報(bào)文:
POST /upload HTTP/1.1 Host:127.0.0.1:5000 Content-Type: multipart/form-data;boundary=xxx ---xxx Content-Disposition:form-data; name="xxhh";filename="bg.jpg" Content-Type:image/jpeg 文件數(shù)據(jù)... --xxx--
我們就可以通過以下js進(jìn)行實(shí)現(xiàn)
const xhr = new XMLHttpRequest(); xhr.open('POST','http://127.0.0.1:5000/upload'); const form = new FormData(); form.append('xxhh',file,'bg.jpg'); // 第一個(gè)參數(shù)對(duì)應(yīng)Content-Disposition中的name // 第二個(gè)參數(shù)為文件數(shù)據(jù)(這里是文件真實(shí)的數(shù)據(jù)并非File對(duì)象) // 第三個(gè)為Content-Disposition中的filename,默認(rèn)為本地文件名 xhr.send(form); xhr.onload = ()=>{ console.log(xhr.responseText); //獲取到響應(yīng)結(jié)果 }
我們通過open
構(gòu)造出請(qǐng)求頭信息,并通過FormData
這個(gè)API讓我們更加簡(jiǎn)單的編寫請(qǐng)求體信息, 它會(huì)自動(dòng)將我們的請(qǐng)求頭信息設(shè)置為Content-Type: multipart/form-data;
并自動(dòng)生成一個(gè)boundary
,使用append
方法可向其添加一個(gè)要發(fā)送字段信息,最后調(diào)用xhr.send(form)
將攜帶數(shù)據(jù)的請(qǐng)求發(fā)出。
以上就是JS獲取本地文件并進(jìn)行網(wǎng)絡(luò)傳輸?shù)拇a詳解的詳細(xì)內(nèi)容,更多關(guān)于JS獲取本地文件并傳輸?shù)馁Y料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
每周一練 之 數(shù)據(jù)結(jié)構(gòu)與算法(Stack)
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)與算法(Stack),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04JavaScript中async和await的使用及隊(duì)列詳情
這篇文章主要介紹了JavaScript中async和await的使用及隊(duì)列詳情,主要圍繞js中async和await簡(jiǎn)單解析展開面試中可能會(huì)問到的關(guān)于隊(duì)列的一些場(chǎng)景和知識(shí)點(diǎn),需要的朋友可以參考一下2022-07-07JavaScript獲取網(wǎng)頁(yè)表單提交方式的方法
這篇文章主要介紹了JavaScript獲取網(wǎng)頁(yè)表單提交方式的方法,可判斷表單提交方式是get還是post,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04如何利用js根據(jù)坐標(biāo)判斷構(gòu)成單個(gè)多邊形是否合法
這篇文章主要給大家介紹了關(guān)于如何利用js根據(jù)坐標(biāo)判斷構(gòu)成單個(gè)多邊形是否合法的相關(guān)資料,文章通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-01-01JavaScript中數(shù)組slice和splice的對(duì)比小結(jié)
相信對(duì)很多學(xué)習(xí)JavaScript語(yǔ)言的人來說,都會(huì)經(jīng)常搞不清slice和splice這兩個(gè)方法。它們雖然名稱相似,但是功能卻完全不同。所以這篇文章就給大家詳細(xì)整理了關(guān)于JavaScript中數(shù)組slice和splice的對(duì)比,有需要的可以參考學(xué)習(xí)。2016-09-09JavaScript無(wú)提示關(guān)閉窗口(兼容IE/Firefox/Chrome)
JavaScript無(wú)提示關(guān)閉當(dāng)前頁(yè)面窗口,兼容IE/Firefox/Chrome (Close the current page window without confirm by JavaScript, support all browsers)2008-11-11JS生成不重復(fù)的隨機(jī)數(shù)組的簡(jiǎn)單實(shí)例
下面小編就為大家?guī)硪黄狫S生成不重復(fù)的隨機(jī)數(shù)組的簡(jiǎn)單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-07-07