您的位置:首页 > Web前端 > HTML5

[转]html5表单上传控件Files API

2015-09-11 11:27 260 查看
表单上传控件:<input type="file" />(IE9及以下不支持下面这些功能,其它浏览器最新版本均已支持。)

1、允许上传文件数量

允许选择多个文件:<input type="file" multiple>
只允许上传一个文件:<input type="file" single>

2、上传指定的文件格式

<input type="file" accept="image/gif,image/png" />

这里的上传格式仅指打开上传弹窗选择文件时默认的文件格式,可手动修改成其它文件格式。

如果不限制上传图片的格式可写成:accept="image/*"

其它格式参考如下:

*.3gppaudio/3gpp, video/3gpp3GPP Audio/Video
*.ac3audio/ac3AC3 Audio
*.asfallpication/vnd.ms-asfAdvanced Streaming Format
*.auaudio/basicAU Audio
*.csstext/cssCascading Style Sheets
*.csvtext/csvComma Separated Values
*.docapplication/mswordMS Word Document
*.dotapplication/mswordMS Word Template
*.dtdapplication/xml-dtdDocument Type Definition
*.dwgimage/vnd.dwgAutoCAD Drawing Database
*.dxfimage/vnd.dxfAutoCAD Drawing Interchange Format
*.gifimage/gifGraphic Interchange Format
*.htmtext/htmlHyperText Markup Language
*.htmltext/htmlHyperText Markup Language
*.jp2image/jp2JPEG-2000
*.jpeimage/jpegJPEG
*.jpegimage/jpegJPEG
*.jpgimage/jpegJPEG
*.jstext/javascript, application/javascriptJavaScript
*.jsonapplication/jsonJavaScript Object Notation
*.mp2audio/mpeg, video/mpegMPEG Audio/Video Stream, Layer II
*.mp3audio/mpegMPEG Audio Stream, Layer III
*.mp4audio/mp4, video/mp4MPEG-4 Audio/Video
*.mpegvideo/mpegMPEG Video Stream, Layer II
*.mpgvideo/mpegMPEG Video Stream, Layer II
*.mppapplication/vnd.ms-projectMS Project Project
*.oggapplication/ogg, audio/oggOgg Vorbis
*.pdfapplication/pdfPortable Document Format
*.pngimage/pngPortable Network Graphics
*.potapplication/vnd.ms-powerpointMS PowerPoint Template
*.ppsapplication/vnd.ms-powerpointMS PowerPoint Slideshow
*.pptapplication/vnd.ms-powerpointMS PowerPoint Presentation
*.rtfapplication/rtf, text/rtfRich Text Format
*.svfimage/vnd.svfSimple Vector Format
*.tifimage/tiffTagged Image Format File
*.tiffimage/tiffTagged Image Format File
*.txttext/plainPlain Text
*.wdbapplication/vnd.ms-worksMS Works Database
*.wpsapplication/vnd.ms-worksWorks Text Document
*.xhtmlapplication/xhtml+xmlExtensible HyperText Markup Language
*.xlcapplication/vnd.ms-excelMS Excel Chart
*.xlmapplication/vnd.ms-excelMS Excel Macro
*.xlsapplication/vnd.ms-excelMS Excel Spreadsheet
*.xltapplication/vnd.ms-excelMS Excel Template
*.xlwapplication/vnd.ms-excelMS Excel Workspace
*.xmltext/xml, application/xmlExtensible Markup Language
*.zipaplication/zipCompressed Archive
3、FileList上传文件数组

FileList对象都是一组文件对象的集合,而文件对象则拥有下列的属性:
name – 文件名(不包含路径)
type – 文件的MIME类型(小写)
size – 文件的尺寸(单位为字节)

lastModifiedDate 为上传文件的最后修改时间

通过上面的几个对象,我们能够控制用户上传的文件大小和文件类型,以便减轻服务器再次检测时的压力,并提升安全系数。

var a=document.getElementById("file");
a.onchange=function(e){
<span style="white-space:pre">    </span>e=e || window.event;
<span style="white-space:pre">    </span>var b=e.target.files;
<span style="white-space:pre">    </span>alert(b[0].name);
}


4、拖动上传

dataTransfer 对象
dropEffect[=sCursorStyle]
设置或获取拖拽操作的类型和要显示的光标类型
copy:复制样式被显示
link:链接样式被显示
move:移动样式被显示
none:默认,没有鼠标样式被定义

effectAllowed[=sEffect]
设置或获取数据传送操作可应用与该对象的源元素
copy 选项被复制
link 选项被dataTransfer作为link方式保存
move 当放置时,对象被移动至目标对象
copylink 选项是被复制还是被作为link方式保存关键在于目标对象
linkmove 选项是被作为link方式保存还是被移动关键在于目标对象
all 所有效果都被支持
none 不支持任何效果
uninitialized 默认不能通过这个属性传递任何值

setData(sFormat,sData) 将指定格式的数据赋值给dataTransfer或者clipboardData sFormat:URL,Text
getData(sFormat) 从dataTransfer或者clipboardData中获取值 sFormat:URL,Text
clearData([sFormat]) 通过dataTransfer或者clipboardData中删除某种格式的数据 sFormat:Text,URL,File,HTML,Image

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#DropZone{border:1px solid #CCC;height:50px;}
</style>
</head>
<body>
<input type="file" multiple accept="image/gif,image/png" id="file">
<div id="DropZone"></div>
<div id="Lists"></div>
<script>
var aa=document.getElementById("file");
aa.onchange=function(){
fileDrop();
}

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!');
}

</script>
</body>
</html>


5、FileReader文件预览,读取文件数据(同时可读取图片文件宽高)

FileReader包含四种异步读取文件的方式:
FileReader.readAsBinaryString(Blob|File) - result属性包含的是file/blob的二进制字符串形式的数据。每个字节由一个0-255的整数表示。
FileReader.readAsText(Blob|File, opt_encoding) - result属性包含的是以文本方式表示的file/blob数据。默认情况下,字符串以'UTF-8'编码方式解码。使用opt_encoding参数可以指定一个不同的格式。
FileReader.readAsDataURL(Blob|File) - result属性包含的是以data URL编码的file/blob数据。
FileReader.readAsArrayBuffer(Blob|File) - result属性包含的是以ArrayBuffer对象表示的file/blob数据。
一旦这些read方法被调用,onloadstart, onprogress, onload, onabort, onerror, onloadend就可以被用来追踪进度。

上传图片预览:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
body{margin:0;padding:0;}
img{vertical-align:bottom;}
</style>
</head>
<body>
<input type="file" multiple accept="image/gif,image/png,,image/jpeg" id="Files">
<div id="Preview"></div>
<ul id="Errors"></ul>
<script>
function fileSelect(e) {
e = e || window.event;

var files = e.target.files;  //FileList Objects
var ireg = /image\/.*/i,
p = document.getElementById('Preview');

var ul = document.getElementById('Errors');
for(var i = 0, f; f = files[i]; i++) {
if(!f.type.match(ireg)) {
//设置错误信息
var li = document.createElement('li');
li.innerHTML = '<li>' + f.name +'不是图片文件.</li>';

ul.appendChild(li);

continue;
}

var reader = new FileReader();

reader.onload = (function(file) {
return function(e) {
var span = document.createElement('span');
var img = new Image;
img.alt=file.name;
img.onload = function() {
console.log(img.height); // image is loaded; sizes are available
};

img.src=this.result;
span.innerHTML = '<img class="thumb" src="'+ this.result +'" alt="'+ file.name +'" />';

p.insertBefore(span, null);
};
})(f);
//读取文件内容
reader.readAsDataURL(f);
}
}

if(window.File && window.FileList && window.FileReader && window.Blob) {
document.getElementById('Files').addEventListener('change', fileSelect, false);
} else {
document.write('您的浏览器不支持File Api');
}
</script>
</body>
</html>


上传txt文件内容预览(需对<>&'"|等符号进行过滤否则会中断读取):

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
body{margin:0;padding:0;}
img{vertical-align:bottom;}
</style>
</head>
<body>
<input type="file" multiple id="Files">
<div id="Preview"></div>
<ul id="Errors"></ul>
<script>
function encodeHTML(source) {
//return source;
return source
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/\"/g, '"');
};
function fileSelect(e) {
e = e || window.event;

var files = e.target.files;  //FileList Objects
var ireg = /text\/.*/i,
p = document.getElementById('Preview');

var ul = document.getElementById('Errors');
for(var i = 0, f; f = files[i]; i++) {
console.log(f.type);
if(!f.type.match(ireg)) {
//设置错误信息
var li = document.createElement('li');
li.innerHTML = '<li>' + f.name +'不是文本文件.</li>';

ul.appendChild(li);

continue;
}

var reader = new FileReader();

reader.onload = (function(file) {
return function(e) {
var div = document.createElement('div');
div.className = "text"
div.innerHTML = encodeHTML(this.result);

p.insertBefore(div, null);
};
})(f);
//读取文件内容
reader.readAsText(f);
}
}

if(window.File && window.FileList && window.FileReader && window.Blob) {
document.getElementById('Files').addEventListener('change', fileSelect, false);
} else {
document.write('您的浏览器不支持File Api');
}
</script>
</body>
</html>


读取上传txt指定区域文本内容:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
body{margin:0;padding:0;}
img{vertical-align:bottom;}
</style>
</head>
<body>
<input type="file" multiple id="Files">
<button type="button" id="buttons" data-start="0" data-end="3">确定</button>
<div id="range"></div>
<div id="content"></div>
<script>

function readBlob(start, end) {
var files = document.getElementById('Files').files;

if(!files.length) {
alert('请选择文件');
return false;
}

var file = files[0],
start = parseInt(start, 10) || 0,
end = parseInt(end, 10) || (file.size - 1);

var r = document.getElementById('range'),
c = document.getElementById('content');

var reader = new FileReader();

reader.onloadend = function(e) {
if(this.readyState == FileReader.DONE) {
c.textContent = this.result;
r.textContent = "Read bytes: " + (start + 1) + " - " + (end + 1) + " of " + file.size + " bytes";
}
};

var blob;

blob = file.slice(start, end + 1, 'text/plain;charset=UTF-8');
reader.readAsBinaryString(blob);
};

try {
document.getElementById('buttons').addEventListener('click', function(e) {
if(e.target.tagName.toLowerCase() == 'button') {
var start = e.target.getAttribute('data-start'),
end = e.target.getAttribute('data-end');

readBlob(start, end);
}
});
} catch(ex) {
alert('something error happens!')
}
</script>
</body>
</html>


File接口提供了slice方法支持把文件切成不同的片段,第一个参数是起始的字节数,第二个参数是结束的字节数,还有一个可选的内容类型字符串可以作为第三个参数。早期的chrome和firefox版本不支持file.slice 可使用file.webkitSlice和file.mozSlice替代,最新版本均支持file.slice。

6、文件读取进度

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form>
<fieldset>
<legend>分度读取文件:</legend>
<input type="file" id="File" />
<input type="button" value="中断" id="Abort" />
<p>
<label>读取进度:</label><progress id="Progress" value="0" max="100"></progress>
</p>
<p id="Status"></p>
</fieldset>
</form>

<script>
var h = {
init: function() {
var me = this;

document.getElementById('File').onchange = me.fileHandler;
document.getElementById('Abort').onclick = me.abortHandler;

me.status = document.getElementById('Status');
me.progress = document.getElementById('Progress');
me.percent = document.getElementById('Percent');

me.loaded = 0;
//每次读取1M
me.step = 1024 * 1024;
me.times = 0;
},
fileHandler: function(e) {
var me = h;

var file = me.file = this.files[0];
var reader = me.reader = new FileReader();

//
me.total = file.size;

reader.onloadstart = me.onLoadStart;
reader.onprogress = me.onProgress;
reader.onabort = me.onAbort;
reader.onerror = me.onerror;
reader.onload = me.onLoad;
reader.onloadend = me.onLoadEnd;
//读取第一块
me.readBlob(file, 0);
},
onLoadStart: function() {
var me = h;
},
onProgress: function(e) {
var me = h;

me.loaded += e.loaded;
//更新进度条
me.progress.value = (me.loaded / me.total) * 100;
},
onAbort: function() {
var me = h;
},
onError: function() {
var me = h;

},
onLoad: function() {
var me = h;

if(me.loaded < me.total) {
me.readBlob(me.loaded);
} else {
me.loaded = me.total;
}
},
onLoadEnd: function() {
var me = h;

},
readBlob: function(start) {
var me = h;

var blob,
file = me.file;

me.times += 1;

if(file.slice) {
blob = file.slice(start, start + me.step + 1);
} else if(file.mozSlice) {
blob = file.mozSlice(start, start + me.step + 1);
}

me.reader.readAsText(blob);
},
abortHandler: function() {
var me = h;

if(me.reader) {
me.reader.abort();
}
}
};

h.init();
</script>
</body>
</html>


参考资料:
http://blog.csdn.net/zhu1988renhui/article/details/7936498 http://blog.csdn.net/zhu1988renhui/article/details/7936525 http://dev.w3.org/2006/webapi/FileAPI/#dfn-filereader http://www.html5rocks.com/zh/tutorials/file/dndfiles/ http://www.w3.org/TR/file-upload/ http://www.w3.org/TR/file-upload/#dfn-filereader http://www.w3.org/TR/file-upload/#dfn-Blob http://www.w3.org/TR/file-upload/#dfn-fileerror http://www.w3.org/TR/progress-events/#Progress http://www.zhangxinxu.com/wordpress/?p=1923 http://www.tfan.org/wp-content/slides/file.html#1
本文代码以chrome测试为主。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: