在做web文件上传时,如果是单文件上传,我们一般可以采用form表单的形式来上传文件。
这种做法用户体验非常的差,我们无法在客户端对用户选取的文件进行validate,无法读取文件大小,无法判断文件类型,无法预览等。。。
如果是多文件上传,js更是回天乏力,虽然也不是不能用js + iframe来模拟,但是很麻烦。。。
但现在有了html5,一切都不同!
html5提供了File API,允许js读取本地文件,但并不能直接访问本地文件,而是要依赖于用户行为,比如用户在type='file'控件上选择了某个文件或者用户将文件拖拽到浏览器上。
一、File Api 浏览器支持检测
File Api给js提供了以下几个接口来访问本地文件系统:
1、File - 单个文件;提供了诸如name、file size、mimetype等只读文件属性。
2、FileList - 一个类数组File对象集合;
3、Blob - 文件对象的二进制原始数据;
File API还提供了一个异步读取文件的接口 - FileReader。
通过检测以下接口是否存在,即可判断浏览器是否支持File Api。
1
2
3
4
5
|
if
(window.File && window.FileReader && window.FileList && window.Blob) {
document.write(
"Great success! All the File APIs are supported."
);
}
else
{
document.write(
'The File APIs are not fully supported in this browser.'
);
}
|
File API主要是用来获取本地文件系统中文件的reference,通过File API我们可以获得一个代表本地文件的js对象,而FileReader通过该File对象即可异步地读取本地文件的内容。
二、form表单的file控件
在html5中,file控件支持选择多个文件,用户选择了某些文件之后,html5为我们提供了一个访问这些文件的对象 - FileList,这是一个类数组集合,每一个元素为一个File对象,File对象中包含了文件的所有可访问信息。
示例的HTML代码如下:
1
2
|
<
input
type
=
"file"
id
=
"Files"
name
=
"files[]"
multiple />
<
div
id
=
"Lists"
></
div
>
|
js代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
function
fileSelect(e) {
e = e || window.event;
var
files = e.target.files;
//FileList Objects
var
output = [];
for
(
var
i = 0, f; f = files[i]; i++) {
output.push(
'<li><strong>'
+ f.name +
'</strong>('
+ f.type +
') - '
+ f.size +
' bytes</li>'
);
}
document.getElementById(
'Lists'
).innerHTML =
'<ul>'
+ output.join(
''
) +
'</ul>'
;
}
if
(window.File && window.FileList && window.FileReader && window.Blob) {
document.getElementById(
'Files'
).addEventListener(
'change'
, fileSelect,
false
);
}
else
{
document.write(
'您的浏览器不支持File Api'
);
}
|
NOTE:File对象还提供了文件的lastModifiedDate属性,不过测试了一下,火狐不支持。
除了可以通过表单file控件访问本地文件外,还可以通过拖放API来访问。
三、Drag And Drop API
html5还提供了一个更快捷的方式来触发读取文件的时机,前面我们已经说过,浏览器不能主动地访问本地操作系统,只能依赖于用户行为,用户想要访问文件时,才去访问本地文件系统。
拖放API能做的事情很多,在这里我只介绍一下它在访问本地文件方面的功能。
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
function
fileDrop(e) {
e = e || window.event;
e.stopPropagation();
// 阻止冒泡
e.preventDefault();
//阻止默认行为
var
files = e.dataTransfer.files;
//FileList
var
output = [];
for
(
var
i = 0, f; f = files[i]; i++) {
output.push(
'<li><strong>'
+ f.name +
'</strong>('
+ f.type +
') - '
+ f.size +
' bytes</li>'
);
}
document.getElementById(
'Lists'
).innerHTML =
'<ul>'
+ output.join(
''
) +
'</ul>'
;
};
function
dragOver(e) {
e = e || window.event;
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect =
'copy'
;
//指定拖放视觉效果
};
var
d = document.getElementById(
'DropZone'
);
try
{
d.addEventListener(
'dragover'
, dragOver,
false
);
d.addEventListener(
'drop'
, fileDrop,
false
)
}
catch
(ex) {
document.write(
'something must be wrong!'
);
}
|
后面将介绍FileReader,通过它具体地读取文件内容。