用于web開發的文件上傳怎么實現

這篇“用于web開發的文件上傳怎么實現”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“用于web開發的文件上傳怎么實現”文章吧。

成都創新互聯公司專注于英山企業網站建設,響應式網站建設,商城網站建設。英山網站建設公司,為英山等地區提供建站服務。全流程定制網站建設,專業設計,全程項目跟蹤,成都創新互聯公司專業和態度為您提供的服務

文件上傳是Web開發常見需求,上傳文件需要用到文件輸入框,如果給文件輸入框添加一個multiple屬性則可以一次選擇多個文件(不支持的瀏覽器會自動忽略這個屬性)

<inputmultipletype="file">

點擊這個輸入框就可以打開瀏覽文件對話框選擇文件了,一般一個輸入框上傳一個文件就行,要上傳多個文件也可以用多個輸入框來處理,這樣做是為了兼容那些不支持multiple屬性的瀏覽器,同時用戶一般也不會選擇多個文件

基本上傳方式

當把文件輸入框放入表單中,提交表單的時候即可將選中的文件一起提交上傳到服務器,需要注意的是由于提交的表單中包含文件,因此要修改一下表單元素的enctype屬性為multipart/form-data

<formaction="#"enctype="multipart/form-data"method="post">

<inputname="file"type="file">

<buttontype="submit">Upload</button>

</form>

這樣上傳方式是傳統的同步上傳,上傳的文件如果很大,往往需要等待很久,上傳完成后頁面還會重新加載,并且必須等待上傳完成后才能繼續操作

早期的瀏覽器并不支持異步上傳,不過可以使用iframe來模擬,在頁面中隱藏一個<iframe>元素,指定一個name值,同時將<form>元素的target屬性值指定為<iframe>元素的name屬性的值,將兩者關聯起來

<formaction="#"enctype="multipart/form-data"method="post"target="upload-frame">

<inputname="file"type="file">

<buttontype="submit">Upload</button>

</form>

<iframeid="upload-frame"name="upload-frame"src="about:blank"style="display:none;"></iframe>

這樣在提交表單上傳的時候,頁面就不會重新加載了,取而代之的是iframe重新加載了,不過iframe原本就是隱藏的,即使重新加載也不會感知到

訪問文件

FileAPI提供了訪問文件的能力,通過輸入框的files屬性訪問,這會得到一個FileList,這是一個集合,如果只選擇了一個文件,那么集合中的第一個元素就是這個文件

varinput=document.querySelector('input[type="file"]')

varfile=input.files[0]

console.log(file.name)//文件名稱

console.log(file.size)//文件大小

console.log(file.type)//文件類型

支持FileAPI的瀏覽器可以參考caniuse

Ajax上傳

由于可以通過FileAPI直接訪問文件內容,再結合XMLHttpRequest對象直接將文件上傳,將其作為參數傳給XMLHttpRequest對象的send方法即可

varxhr=newXMLHttpRequest()

xhr.open('POST','/upload/url',true)

xhr.send(file)

不過一些原因不建議直接這樣傳遞文件,而是使用FormData對象來包裝需要上傳的文件,FormData是一個構造函數,使用的時候先new一個實例,然后通過實例的append方法向其中添加數據,直接把需要上傳的文件添加進去

varformData=newFormData()

formData.append('file',file,file.name)//第3個參數是文件名稱

formData.append('username','Mary')//還可以添加額外的參數

甚至也可以直接把表單元素作為實例化參數,這樣整個表單中的數據就全部包含進去了

varformData=newFormData(document.querySelector('form'))

數據準備好后,就是上傳了,同樣是作為參數傳給XMLHttpRequest對象的send方法

varxhr=newXMLHttpRequest()

xhr.open('POST','/upload/url',true)

xhr.send(formData)

監測上傳進度

XMLHttpRequest對象還提供了一個progress事件,基于這個事件可以知道上傳進度如何

varxhr=newXMLHttpRequest()

xhr.open('POST','/upload/url',true)

xhr.upload.onprogress=progressHandler//這個函數接下來定義

上傳的progress事件由xhr.upload對象觸發,在事件處理程序中使用這個事件對象的loaded(已上傳字節數)和total(總數)屬性來計算上傳的進度

functionprogressHandler(e){

varpercent=Math.round((e.loaded/e.total)*100)

}

上面的計算會得到一個表示完成百分比的數字,不過這兩個值也不一定總會有,保險一點先判斷一下事件對象的lengthComputable屬性

functionprogressHandler(e){

if(e.lengthComputable){

varpercent=Math.round((e.loaded/e.total)*100)

}

}

支持Ajax上傳的瀏覽器可以參考caniusehttps://caniuse.com/#feat=xhr2

分割上傳

使用文件對象的slice方法可以分割文件,給該方法傳遞兩個參數,一個起始位置和一個結束位置,這會返回一個新的Blob對象,包含原文件從起始位置到結束位置的那一部分(文件File對象其實也是Blob對象,這可以通過fileinstanceofBlob確定,Blob是File的父類)

varblob=file.slice(0,1024)//文件從字節位置0到字節位置1024那1KB

將文件分割成幾個Blob對象分別上傳就能實現將大文件分割上傳

functionupload(file){

letformData=newFormData()

formData.append('file',file)

letxhr=newXMLHttpRequest()

xhr.open('POST','/upload/url',true)

xhr.send(formData)

}

varblob=file.slice(0,1024)

upload(blob)//上傳第一部分

varblob2=file.slice(1024,2048)

upload(blob2)//上傳第二部分

//上傳剩余部分

通常用一個循環來處理更方便

varpos=0//起始位置

varsize=1024//塊的大小

while(pos<file.size){

letblob=file.slice(pos,pos+size)//結束位置=起始位置+塊大小

upload(blob)

pos+=size//下次從結束位置開始繼續分割

}

服務器接收到分塊文件進行重新組裝的代碼就不在這里展示了

使用這種方式上傳文件會一次性發送多個HTTP請求,那么如何處理這種多個請求同時發送的情況呢?方法有很多,可以用Promise來處理,讓每次上傳都返回一個promise對象,然后用Promise.all方法來合并處理,Promise.all方法接受一個數組作為參數,因此將每次上傳返回的promise對象放在一個數組中

varpromises=[]

while(pos<file.size){

letblob=file.slice(pos,pos+size)

promises.push(upload(blob))//upload應該返回一個promise

pos+=size

}

同時改造一下upload函數使其返回一個promise

functionupload(file){

returnnewPromise((resolve,reject)=>{

letformData=newFormData()

formData.append('file',file)

letxhr=newXMLHttpRequest()

xhr.open('POST','/upload/url',true)

xhr.onload=()=>resolve(xhr.responseText)

xhr.onerror=()=>reject(xhr.statusText)

xhr.send(formData)

})

}

當一切完成后

Promise.all(promises).then((response)=>{

console.log('Uploadsuccess!')

}).catch((err)=>{

console.log(err)

})

支持文件分割的瀏覽器可以參考caniuse

判斷一下文件對象是否有該方法就能知道瀏覽器是否支持該方法,對于早期的部分版本瀏覽器需要加上對應的瀏覽器廠商前綴

varslice=file.slice||file.webkitSlice||file.mozSlice

if(slice){

letblob=slice.call(file,0,1024)//call

upload(blob)

}else{

upload(file)//不支持分割就只能直接上傳整個文件了,或者提示文件過大

}

拖拽上傳

通過拖拽API可以實現拖拽文件上傳,默認情況下,拖拽一個文件到瀏覽器中,瀏覽器會嘗試打開這個文件,要使用拖拽功能需要阻止這個默認行為

document.addEventListener('dragover',function(e){

e.preventDefault()

e.stopPropagation()

})

任意指定一個元素來作為釋放拖拽的區域,給一個元素綁定drop事件

varelement=document.querySelector('label')

element.addEventListener('drop',function(e){

e.preventDefault()

e.stopPropagation()

//...

})

通過該事件對象的dataTransfer屬性獲取文件,然后上傳即可

varfile=e.dataTransfer.files[0]

upload(file)//upload函數前面已經定義

選擇類型

給文件輸入框添加accept屬性即可指定選擇文件的類型,比如要選擇png格式的圖片,則指定其值為image/png,如果要允許選擇所有類型的圖片,就是image/*

<inputaccept="image/*"type="file">

添加capture屬性可以調用設備機能,比如capture="camera"可以調用相機拍照,不過這并不是一個標準屬性,不同設備實現方式也不一樣,需要注意

<inputaccept="image/*"capture="camera"type="file">

經測iOS設備添加該屬性后只能拍照而不能從相冊選擇文件了,所以判斷一下

if(iOS){//iOS用navigator.userAgent判斷

input.removeAttribute('capture')

}

不支持的瀏覽器會自動忽略這些屬性

自定義樣式

文件輸入框在各個瀏覽器中呈現的樣子都不大相同,而且給input定義樣式也不是那么方便,如果有需要應用自定義樣式,有一個技巧,可以用一個label關聯到這個文件輸入框,當點擊這個label元素的時候就會觸發文件輸入框的點擊,打開瀏覽文件的對話框,相當于點擊了文件輸入框一樣的效果

<labelfor="file-input"></label>

<inputid="file-input"style="clip:rect(0,0,0,0);position:absolute;"type="file">

這時就可以將原本的文件輸入框隱藏了,然后給label元素任意地應用樣式,畢竟要給label元素應用樣式比input方便得多

以上就是關于“用于web開發的文件上傳怎么實現”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注創新互聯行業資訊頻道。

文章標題:用于web開發的文件上傳怎么實現
轉載來于:http://m.kartarina.com/article32/pipjsc.html

成都網站建設公司_創新互聯,為您提供靜態網站網站排名網站營銷虛擬主機用戶體驗建站公司

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

外貿網站建設
主站蜘蛛池模板: 日韩AV无码一区二区三区不卡毛片| 日韩精品无码AV成人观看| 久久久久久久无码高潮| 亚洲av永久无码精品古装片| 亚洲AV无码AV男人的天堂| 无码国产精品一区二区免费式直播 | 少妇性饥渴无码A区免费| 无码国产色欲XXXX视频| 国产精品无码亚洲一区二区三区 | 人妻少妇乱子伦无码视频专区| 久久AV无码精品人妻出轨| 精品日韩亚洲AV无码一区二区三区 | 亚洲av成人无码久久精品| 特黄熟妇丰满人妻无码| 亚洲最大天堂无码精品区| 中文字幕无码成人免费视频| 国产精品午夜福利在线无码| 国产a v无码专区亚洲av| 亚洲av无码电影网| 中文精品无码中文字幕无码专区| 日日摸夜夜爽无码毛片精选| 国产怡春院无码一区二区| 亚洲AV成人无码天堂| 少妇无码一区二区三区免费| 人妻无码中文字幕免费视频蜜桃| 一夲道dvd高清无码| 久久亚洲AV无码精品色午夜 | 99久久国产热无码精品免费| 国产精品无码专区| 久久AV高清无码| 久久午夜夜伦鲁鲁片无码免费| 亚洲&#228;v永久无码精品天堂久久| 亚洲成av人片在线观看天堂无码| 亚洲AV无码专区在线亚| 亚洲爆乳无码专区www| 无码办公室丝袜OL中文字幕 | 在线观看无码的免费网站| 久青草无码视频在线观看| 曰韩无码AV片免费播放不卡| 亚洲av麻豆aⅴ无码电影| 亚洲一级特黄大片无码毛片|