使用<input type='file'>
,我们可以实现上传文件, 并且监听change
事件,通过事件对象event.target.files
可以 获取到我们上传的文件集合FileList
, 集合内部包含许多个File
文件对象,每一个文件对象包含以下属性。
- name: 本地文件系统当中该文件的名称
- size:文件的大小,以字节为单位
- type: 文件的类型,字符串
- lastModified:字符串, 文件上一次被修改的日期
上面的方式仅仅是显示文件的信息,但是并不能读取文件
FileReader
该api支持读取文件,并提供相应的回调事件,使用方式如下
var reader = new FileReader()
reader.readAsText(前面提到的单个file文件对象)
FileReader
对象提供以下几种方法和回调事件, 以上面的实例reader
为例
方法
reader.readAsText(前面提到的file文件对象, encoding)
: 以纯文本形式读取文件,可选参数是用于指定编码的。读取结果保存在reader.result
中。reader.readAsDataURL(file对象)
:读取文件并讲文件以数据URL
的形式保存在reader.result
中。一般拿来读取图片对应的File
对象,会得到一个base64
编码的URL
,可以直接放到img
标签的src
属性中来展示reader.readAsBinaryString(file对象)
:以二进制的方式读取文件,并使用字符串保存到reader.result
当中reader.readAsArrayBuffer(file对象)
: 以ArrayBuffer
的形式读取文件,并保存在reader.result
当中reader.abort()
: 如果想中断读取过程,可以调用这个函数。
回调函数
progress
: 每50ms
就会触发一次,可以通过访问事件对象event
的三个属性,来实现进度条的功能lengthComputable
: 是否开始读取loaded
: 已经读取了多少total
: 总共需要读取多少
error
: 当由于种种原因,无法读取文件的时候,就会触发这个事件,而且不会触发load
事件。错误码可以通过reader.error.code
来查看- 1: 表示未找到文件
- 2:表示安全性错误
- 3: 表示读取中断
- 4: 表示文件不可读
- 5: 编码错误
load
: 加载成功之后再触发abort
: 当调用reader.abort()
中断读取过程的时候,会触发这个事件。loadend
: 最后触发,不管怎么都会触发的一个事件
读取部分内容
有时候我们只想读取文件的一部分内容,还记得前面的File
对象吗。我们可以提前用slice()
方法对这个对象进行处理, 处理之后将得到一个Blob
实例,这个是File
文件对象的父类型,可以直接拿来使用。
不同浏览器的支持不相同
- chrome:
webkitSlice()
- firefox:
mozSlice()
silce()
该方法接受两个参数,startByte
开始读取的字节位置、length
读取的长度
使用方法如下:
var reader = new FileReader()
var file = document.getElementsByTag('input')[0]
var blob = file.slice(0, 100) // 注意实际使用当中要处理兼容性问题
reader.readAsText(blob) // 这样就可以了
对象URL
对象URL
也称为Blob URL
,它可以引用File、Blob
对象中的数据。还记得在前面我们都是直接将File、Blob
对象传入FileReader
的,这个是需要将文件读取到javaScript
中的,但是如果使用FileReader
的时候传入参数时,使用对象URL
来代替File、Blob
对象,那么它会直接去对象URL
对应的地址读取数据,省去了读取到javaScript
的这个阶段。
window.URL.createObjectURL()
, 这里也涉及到兼容性,chrome当中应该叫做webkitURL
。
使用方法
var reader = new FileReader()
var file = document.getElementsByTag('input')[0]
var objectURL = window.URL.createObjectURL(file) // 这样使用
reader.readAsText(objectURL) // 这样就可以了
另外我们在前面读取图片并展示的时候是使用的FileReader.readAsDataURL
。现在我们可以直接使用对象URL
来代替它来获得URL
,使用对象URL
之后, img
的src
属性使用这个URL
就会自动去找到相应的内存并读取数据然后展示出来
使用方法
var reader = new FileReader()
var file = document.getElementsByTag('input')[0]
var img = document.getElementsByTag('img')[0]
var objectURL = window.URL.createObjectURL(file) // 这样使用
img.src = objectURL
对象URL
的内存释放,需要我们手动调用window.URL.revokeObjectURL(objectURL)
(这里也有兼容,chrome中是webkitURL
)。
读取施放的文件
结合html5的drop
事件,可以在回调函数中使用event.dataTranser.files
来读取文件,和使用表单上传得到的文件对象相同
使用XHR上传文件
有两种方式可以实现文件上传
- 使用
FileReader
来读取文件对象的内容,然后使用POST
方式,并把读取到的文件内容放到send()
方法中。但是这种方式有一个缺点,这样是传递的是文件的内容,因而服务器端必须收集提交的内容,然后将它保存到一个文件中去 - 使用
FomrData
以表单键值对的方式提交文件,而且不需要使用FileReader
,直接传入文件对象即可,使用方法如下
var data = new Data(),
length = files.length,
i = 0;
while( i < length ) {
data.append('file' + i, files[i])
i++
}
xhr.send(data)