一、引言
本文會詳細介紹XMLHttpRequest上傳部分及相關的理論知識笋粟。
不了解XMLHttpRequest對象的同學請移步XMLHttpRequest對象API部分
二屈扎、假象XMLHttpRequest對象不存在
在介紹上傳這部分知識前埃唯,我思考了如何讓剛接觸這部分的前端人員更好地理解文件上傳。
1鹰晨、首先假象XMLHttpRequest對象不存在
2墨叛、我(你應該想是你)是開發(fā)瀏覽器文件上傳接口的負責人
3、最簡單的一個思路:
1)獲取電腦磁盤文件的控件或接口(file表單控件)
2)上傳到瀏覽器內存中的控件或接口(FileReader)
3)JavaScript腳本上傳到服務器端的接口(XMLHttpRequest的upload屬性)
1模蜡、file表單控件
1)基本屬性
<input type="file" id="file" name="fileName" multiple="multiple"/>
name:控件名稱
multiple:是否支持多選
注意 name一般是服務器端給定的字段
文件過濾選擇框(個人感覺慎用漠趁,篩選速度特別慢,可以做上傳前的文件驗證)
<input type="file" accept="application/msexcel" /> ?
accept屬性列表1.accept="application/msexcel"
2.accept="application/msword"
3.accept="application/pdf"
4.accept="application/poscript"
5.accept="application/rtf"
6.accept="application/x-zip-compressed"
7.accept="audio/basic"
8.accept="audio/x-aiff"
9.accept="audio/x-mpeg"
10.accept="audio/x-pn/realaudio"
11.accept="audio/x-waw"
12.accept="image/gif"
13.accept="image/jpeg"
14.accept="image/tiff"
15.accept="image/x-ms-bmp"
16.accept="image/x-photo-cd"
17.accept="image/x-png"
18.accept="image/x-portablebitmap"
19.accept="image/x-portable-greymap"
20.accept="image/x-portable-pixmap"
21.accept="image/x-rgb"
22.accept="text/html"
23.accept="text/plain"
24.accept="video/quicktime"
25.accept="video/x-mpeg2"
26.accept="video/x-msvideo"
2)獲取控件信息
var file = document.getElementById('file').files
file類型為數組
file[i]儲存每個上傳文件的一些信息哩牍,如下圖:
注意:經過測試上傳各種類型文件棚潦,打印出來的type屬性,有些文件type屬性為空膝昆,所以所以想檢查文件類型的話丸边,建議取name屬性 利用indexOf()檢查叠必,file控件信息只能檢查文件名是否符合要求,如果想要檢查文件里面的一些內容或屬性妹窖,可能需要通過其他前端接口實現纬朝,下面奉上文件大小轉化的一個小方法。
function readFileSize(file,retain){
? ? ?let formatSize='';
? ? ?let size = file.size/1024;
? ? ?let typeArr=["KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
? ? ? if(size<1){
? ? ? ? ? formatSize=file.size+'Byte'
? ? ? ? }else{
? ? ? ? ? ? ? for(let i=0;size>1;size=size/1024,i++){
? ? ? ? ? ? ? ? ? formatSize=size.toFixed(retain)+typeArr[i]
? ? ? ? ? ? ?}
? ? ? ? ?}
? ? ?return formatSize
}
只用JavaScript初始化?file對象還有待研究骄呼,以后會深入研究共苛,請往下看,來介紹文件上傳的三大巨頭之一 FileReader對象
2蜓萄、FileReader
1)定義
<1>html5新增加的接口
<2>JavaScript對象
<3>將磁盤文件讀取到瀏覽器內存中
<4>初始化 var readFile = new FileReader()
2)method
readFile.readAsBinaryString(file) ? ? ?將文件讀取為二進制編碼
readFile.readAsText(file,[encoding]) ? ? 將文件讀取為文本 編碼默認為utf-8
readFile.readAsDataURL(file) ? ? ? ? ? ? ? ? 將文件讀取為DataURL
abort ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 中斷讀取操作
3)event
onabort ? ? ? ? ? ?中斷讀取
onerror ? ? ? ? ? ?讀取出錯
onloadstart ? ? 開始讀取
onprogress ? ? ?正在讀取
onload ? ? ? ? ? ? ? 成功讀取
onloadend ? ? ? ? 讀取完成(無論成功還是失斢缇ァ)
FileReader與XMLHttpRequest有些類似,你可以把readAsBinaryString ?readAsText readAsDataUrl類比成send方法,FileReader相對簡單一些嫉沽,沒有readyState屬性和open方法辟犀,兩者區(qū)別是 FileReader是從本地上傳文件到瀏覽器,XMLHttpRequest是從本地上傳到服務器端绸硕,兩者根本是依賴file控件對文件進行一些處理堂竟。
3、FormData
1)模擬表單控件
2)上傳二進制文件
3)初始化 var formdata = new FormData(data)
data類型為dom對象 可以傳遞form表單 file
4)append()方法 (可以添加file對象或者blob對象)
formdata.append('name',[file或者blob對象],'fileName')
formdata.append()
4玻佩、Blob對象
1)File接口是基于Blob
2)Blob對象可以看做是存放二進制數據的容器出嘹,此外還可以通過Blob設置二進制數據的MINE類型
3)MINE類型
MIME(Multipurpose Internet Mail Extensions)多用途互聯網郵件擴展類型。是設定某種擴展名的文件用一種應用程序來打開的方式類型咬崔,當該擴展名文件被訪問的時候税稼,瀏覽器會自動使用指定應用程序來打開,下圖附上常見的MIME類型刁赦,百度搜的娶聘,所以可能存在錯誤,請抱著懷疑的態(tài)度使用此圖
4)初始化 var blob = new Blob(dataArr:Array<any>,opt:{type:string});
dataArr:數組甚脉,數據類型可以是任意多個ArrayBuffer,ArrayBufferView,Blob或者DOMString對象
opt:對象,用于設置Blob對象的屬性(如:MIME類型)
5)blob.size 實例的長度
6)blob.slice(start,end,MIME)?
slice方法跟JavaScript很多對象(如字符串)的方法基本一樣铆农,多了第三個參數(見上文)
多說一句牺氨,利用這個方法可以做大文件分割,上傳墩剖,未來的幾篇中會有介紹猴凹,到時候會有連接,敬請期待岭皂。?
7)blob.close()
釋放底層內存資源
8)ArrayBuffer ArrayBufferView 的介紹 有一篇文章介紹很全面了(這個部分適合單獨寫一篇文章)
https://www.cnblogs.com/copperhaze/p/6149041.html
5郊霎、XMLHttpRequest upload屬性
1)本文的重頭角色 文件上傳
前面說了這么多,都是知識鋪墊爷绘,文件上傳书劝,一句話:
通過FormData .append(name,data,fileName)將數據傳遞給后端
2)XMLHttpRequest的upload屬性进倍,著重說一下onprogress這個事件,其他事件不明白的回到第一篇重新看购对。
xhr.upload.onprogress=function(event){
//上傳中的一些屬性猾昆,這個事件是異步的
var total = event.total;
var loaded = event.load
var progress = Number(loaded/total).toFixed(2)*100+'%'
console.log(progress)
}
3)下載進度進度事件
XMLHttpRequest.onprogress=function(event){
? ? ? // 這個后面會介紹到
}
正所謂工欲善其事必先利其器,以上是XMLHttpRequest對象以及相關的基礎知識骡苞,有些很抽象垂蜗,有些介紹的也不是很全面,有些可能有還有一些問題(對于編程的學習理解:實踐是檢驗真理的唯一途徑解幽,但不是確定真理的方法贴见,任何通過實踐掌握的真理都需要辯證地對待。)躲株,但是了解掌握了以上兩篇的內容片部,才能更深刻的理解XMLHttpRequest對象,相對于原型徘溢,閉包吞琐,異步這些概念來說,我覺得XMLHttpRequest對象更加抽象然爆,因為沒有一定的后端基礎站粟,可能沒法更好的理解它的本質,下一篇文章會結合demo著重介紹一下XMLHttpRequest的用法曾雕,會涉及到canvas奴烙、拖拽(html5的api)、vue剖张、react切诀、nodejs的知識。