位置: IT常識(shí) - 正文
推薦整理分享web前端文件上傳可選擇的4種方式(前端 上傳文件),希望有所幫助,僅作參考,歡迎閱讀內(nèi)容。
文章相關(guān)熱門搜索詞:前端實(shí)現(xiàn)文件上傳,web前端圖片上傳,web前端文件上傳不了,前端上傳文件到后端,前端上傳文件夾,前端上傳文件到后端,前端 上傳文件,前端實(shí)現(xiàn)文件上傳,內(nèi)容如對(duì)您有幫助,希望把文章鏈接給更多的朋友!
在web前端開發(fā)中,文件上傳屬于很常見的功能,不論是圖片、還是文檔等等資源,或多或少會(huì)有上傳的需求。一般都是從添加文件開始,然后讀取文件信息,再通過一定的方式將文件上傳到服務(wù)器上,以供后續(xù)展示或下載使用。 本文將講述文件上傳中所能用到的4種添加讀取文件的方式:
input上傳控件拖拽文件粘貼文件File System Access APIinput上傳控件首先介紹的,就是最常用的html表單控件:input[type=file],它允許用戶打開系統(tǒng)的文件選擇框,選擇相應(yīng)文件后加載并讀取到相關(guān)文件信息,它支持單個(gè)文件或多個(gè)文件,多文件選擇增加屬性:multiple。 input上傳控件的瀏覽器支持度最高,作為html的基礎(chǔ)標(biāo)簽功能,一直都是web開發(fā)中使用最多的一種文件上傳方式。 它支持的主要屬性:
multiple:允許用戶選擇多個(gè)文件進(jìn)行添加accept:指定文件上傳時(shí)能接受的文件類型(MIME),如 image/png、image/*、video/* 等等html控件代碼如下,接受批量添加圖片文件:
<input id="fileInput" type="file" accept="image/*" multiple onchange="selectFile()" />以上代碼添加了 onchange 事件,當(dāng)選中不同文件時(shí),可以獲取到文件信息:
const fileInput = document.getElementById('fileInput')function selectFile () { const file = fileInput.files[0]}上面的js代碼,就是監(jiān)聽事件的函數(shù),通過元素對(duì)象,讀取正在添加的文件信息。 或者也可以添加事件監(jiān)聽器,同樣能讀取到文件信息:
document.getElementById('fileInput').addEventListener('change', (e) => { const file = e.target.files[0]}, false)這里讀取的上傳控件元素對(duì)象的文件屬性 files,它是 FileList 對(duì)象,一個(gè)針對(duì) File 對(duì)象的集合。
文件信息是使用 File 對(duì)象API,用于接收文件,具體的介紹可見博文 詳解前端二進(jìn)制:Blob、File、FileReader、ArrayBuffer、TypeArray、DataView
修改上傳控件樣式input文件上傳控件,之前被詬病比較多的就是樣式太單一,在整體設(shè)計(jì)風(fēng)格上會(huì)有很多局限,但我們可以使用css樣式中的一個(gè)偽元素來美化該控件。 這個(gè)偽元素就是 ::file-selector-button,通過它可以對(duì)上傳控件按鈕進(jìn)行顏色字體背景邊框等進(jìn)行各種樣式設(shè)置。具體信息可見博文CSS偽元素詳解以及偽元素與偽類的區(qū)別
input::file-selector-button { border: 1px solid #f00; font-size: 20px; border-radius: 5px; background-color: azure;}以上代碼,即通過偽元素對(duì)上傳控件按鈕進(jìn)行了樣式的修改,效果如下圖。 當(dāng)然,這個(gè)偽元素只能修改按鈕的樣式,至于上傳控件的其他部分包括文字內(nèi)容,無法修改,仍然會(huì)較影響設(shè)計(jì),這時(shí)候我們就需要使用另外的方式,比如隱藏上傳控件。
隱藏上傳控件我們只需要讓上傳控件隱藏不顯示,但在點(diǎn)擊的時(shí)候還能夠觸發(fā)上傳控件的文件選擇框,就能達(dá)到自定義各種好看樣式的上傳控件的目的。 隱藏上傳控件的方式有很多種,下面介紹其中一種,通過透明度的方式,先設(shè)置一個(gè)外部div元素,div內(nèi)添加input上傳元素,并設(shè)置透明度為0,達(dá)到不顯示的目的,代碼如下:
<div class="input-container"> 點(diǎn)擊 <span style="color: red;">選擇文件</span> 進(jìn)行上傳 <input class="input-file" type="file" name="file" multiple="multiple" /></div>.input-container { position: relative; width: 250px; margin: 20px 0;}.input-file { position: absolute; top: 0; left: 0; margin: 0; opacity: 0;}以上代碼,input上傳控件元素通過絕對(duì)定位的方式置于div上層,透明度為0隱藏,視覺上只會(huì)顯示底層div的內(nèi)容(我們可自定義樣式),但input控件會(huì)優(yōu)先響應(yīng)點(diǎn)擊事件,這樣就可以達(dá)到添加文件的目的。 當(dāng)然,類似隱藏的方法還有多種,基于css樣式實(shí)現(xiàn),可以設(shè)計(jì)出更多更好看的文件上傳組件。
拖拽文件第二種介紹的添加文件的方式是拖拽文件,就是通過拖放(drag and drop)過程中的事件監(jiān)聽讀取文件。主要針對(duì)的是三個(gè)拖拽相關(guān)的事件:
dragenter:拖拽進(jìn)入當(dāng)前節(jié)點(diǎn)時(shí)觸發(fā)dragover:拖拽位于節(jié)點(diǎn)上方時(shí),持續(xù)觸發(fā)drop:當(dāng)拖拽至目標(biāo)節(jié)點(diǎn),釋放時(shí)觸發(fā)我們只需要在頁面上添加一個(gè)div元素標(biāo)簽,設(shè)置一定的區(qū)域大小,對(duì)這個(gè)元素的拖放事件進(jìn)行監(jiān)聽即可:
const dropArea = document.getElementById('dropArea')const stopPropagation = (e) => { e.stopPropagation() e.preventDefault()}dropArea.addEventListener('dragenter', stopPropagation, false)dropArea.addEventListener('dragover', stopPropagation, false)dropArea.addEventListener('drop', (dragEvent) => { stopPropagation(dragEvent) const file = dragEvent.dataTransfer.files[0]}, false)以上代碼,監(jiān)聽了拖放事件,當(dāng)我們從電腦上拖動(dòng)一個(gè)文件到指定div區(qū)域內(nèi),釋放以后,就能獲取了drop事件對(duì)象 DragEvent,它擁有一個(gè)獨(dú)有屬性 dataTransfer,是一個(gè) DataTransfer 對(duì)象,能讀取到文件屬性 ‘files’。 接下來,我們了解下 DataTransfer 對(duì)象。
DatatransferDatatransfer 對(duì)象用于獲取拖放事件中傳輸?shù)臄?shù)據(jù)。所有的拖放事件都包含一個(gè)該類型的屬性。 我們?cè)谑录O(jiān)聽中讀取到該對(duì)象后,可以從它的屬性里讀取到需要的數(shù)據(jù),如文件信息。 該對(duì)象除了從拖放事件中獲取以外,還能從 ClipboardEvent.clipboardData 剪切板事件上獲取(后文會(huì)介紹)。
Datatransfer 對(duì)象擁有的屬性和方法:
dropEffect:獲取當(dāng)前選定的拖放操作類型或者設(shè)置的為一個(gè)新的類型。值必須為none, copy, link或move。effectAllowed:提供所有可用的操作類型。必須是none, copy, copyLink, copyMove, link, linkMove, move, all or uninitialized 之一。files:包含數(shù)據(jù)傳輸中可用的所有本地文件的列表。items:只讀,提供一個(gè)包含所有拖動(dòng)數(shù)據(jù)列表的DataTransferItemList對(duì)象。types:只讀,一個(gè)提供dragstart事件中設(shè)置的格式的字符串?dāng)?shù)組。clearData():刪除與給定類型關(guān)聯(lián)的數(shù)據(jù)。不給定參數(shù)則刪除所有g(shù)etData():檢索給定類型的數(shù)據(jù)。setData():設(shè)置給定類型的數(shù)據(jù)。不存在則添加到末尾,存在則替換相同位置的數(shù)據(jù)。setDragImage():用于設(shè)置自定義的拖動(dòng)圖像。粘貼文件除了拖拽文件以外,還有依賴剪切板的粘貼文件的方式,通過復(fù)制文件,并在指定元素區(qū)域內(nèi)粘貼文件,這個(gè)時(shí)候,我們監(jiān)聽元素的 onpaste 事件,就可以得到想要的文件了。
onpaste事件:在將剪切板內(nèi)容粘貼到文檔時(shí)觸發(fā)的事件,事件對(duì)象 ClipboardEvent,擁有一個(gè) clipboardData 只讀屬性,存放剪切板的數(shù)據(jù),它是一個(gè)DataTransfer對(duì)象(見上文)。 有了這個(gè)事件和相應(yīng)的屬性,實(shí)現(xiàn)文件讀取就比較方便了:
document.getElementById('textarea').onpaste = (clipboardEvent) => { clipboardEvent.stopPropagation() clipboardEvent.stopImmediatePropagation() const { items, files } = clipboardEvent.clipboardData if (files && files.length) { const file = files[0] }}以上代碼,通過監(jiān)聽一個(gè) textarea 元素的 onpaste 事件,讀取到 clipboardData 屬性,包含了 files,就讀取到了文件信息,使用上也較為方便。
粘貼的方式,除了文件以外,文本內(nèi)容之類的數(shù)據(jù)也可以處理。
File System Access APIFile System Access API 文件系統(tǒng)訪問API,允許訪問讀寫文件及管理功能。它擁有多個(gè)API對(duì)象和方法,能夠從用戶的本地設(shè)備上進(jìn)行文件交互,核心功能包括讀寫文件、訪問目錄結(jié)構(gòu)等等。它的瀏覽器支持正在慢慢變好,chrome、edge與opera都已支持,然而firefox還不支持。 下文將著重介紹文件讀取的API對(duì)象和方法,讓我們能了解這種新的文件讀取的方式。
showOpenFilePickershowOpenFilePicker 是用于打開文件選擇框,選中并添加文件的一個(gè)異步方法,支持 async/await。 它的語法:showOpenFilePicker(options)。
options 可選屬性對(duì)象:
multiple:布爾值,是否能選擇多個(gè)文件。默認(rèn)false,表示只能選擇一個(gè)文件。excludeAcceptAllOption:布爾值,是否排除types對(duì)象中所有的accept文件類型。默認(rèn)false,不排除。types:可選的文件類型數(shù)組,數(shù)組元素也是對(duì)象,支持以下參數(shù):description:表示文件或者文件夾的描述。accept:接受的文件類型,對(duì)象,用法如 { 'image/*': ['.png', '.gif', '.jpeg', '.jpg'] }。showOpenFilePicker 方法返回一個(gè) FileSystemFileHandle 對(duì)象數(shù)組,用來處理文件信息。
FileSystemHandle 對(duì)象提供一個(gè)系統(tǒng)文件的句柄,用于讀取文件對(duì)象。它提供了一個(gè)方法:getFile(),返回文件對(duì)象,支持 async/await。 下面看一個(gè)具體的示例:
<button id="openImageFile">打開圖片</button>document.getElementById('openImageFile').addEventListener('click', async () => { const handle = await showOpenFilePicker({ multiple: true, types: [{ description: '圖片', accept: { 'image/png': ['.jpg', '.png'] } }] }) if (handle && handle.length) { const handleFile = handle[0] const file = await handleFile.getFile() }}, false)以上代碼,通過按鈕的click事件,使用showOpenFilePicker方法打開選擇文件框,添加一個(gè)文件。
上傳讀取到文件信息以后,就是將文件上傳到服務(wù)器上,可以使用基本的上傳方式,HTML表單:
<form action="url" enctype="multipart/form-data" method="post"> <input name="fileInput" type="file" /> <button type="submit">提交</button></form>以上代碼,就是通過form表單,以 post 的方式將文件上傳到 action 屬性對(duì)應(yīng)的url上傳鏈接。 這種方式一般針對(duì)的就是input文件上傳控件。
除了HTML表單的方式以外,我們還是可以使用 FormData 對(duì)象,構(gòu)造一個(gè)表單數(shù)據(jù),通過ajax等方式進(jìn)行異步數(shù)據(jù)上傳:
const formData = new FormData()formData.append('file', file, file.name)const xhr = new XMLHttpRequest()xhr.open('POST', 'url', true)xhr.send(formData)以上代碼,就是通過構(gòu)造一個(gè) formData 實(shí)例,添加文件數(shù)據(jù),通過 xhr 的方式提交到對(duì)應(yīng)的url上傳鏈接。 構(gòu)造 FormData 對(duì)象的方式,適用于以上4種文件讀取方式,只要獲取到文件信息,就可以通過這種方式上傳到服務(wù)器。
總結(jié)本文總結(jié)了前端web當(dāng)前能夠添加讀取文件的4種方式,如果我們需要開發(fā)一個(gè)比較完善的圖片上傳組件,那么可能需要點(diǎn)擊、拖拽、粘貼多種功能,這就需要使用到前三種文件讀取方式。文件系統(tǒng)訪問API鑒于兼容性還有待提升,我們可以作為后備的方案使用。 有了文件讀取的方式,那我們要完成上傳功能,就可以使用 HTML表單 提交,或者 FormData 對(duì)象上傳了。
上一篇:梵凈山,中國(guó)西南部 (? zhuxiaophotography/Shutterstock)(梵凈山原名)
下一篇:[Web安全入門]BURP基本使用詳解(web安全如何入門)
網(wǎng)站地圖: 企業(yè)信息 工商信息 財(cái)稅知識(shí) 網(wǎng)絡(luò)常識(shí) 編程技術(shù)
友情鏈接: 武漢網(wǎng)站建設(shè)