一、引言
本文会详细介绍XMLHttpRequest上传部分及相关的理论知识。
不了解XMLHttpRequest对象的同学请移步XMLHttpRequest对象API部分
二、假象XMLHttpRequest对象不存在
在介绍上传这部分知识前,我思考了如何让刚接触这部分的前端人员更好地理解文件上传。
1、首先假象XMLHttpRequest对象不存在
2、我(你应该想是你)是开发浏览器文件上传接口的负责人
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方法,两者区别是 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类型,百度搜的,所以可能存在错误,请抱着怀疑的态度使用此图
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的知识。