在html4的年代,咱们若是要在网页上呈现一张用户本地的图片,须要用户先把图片上传到服务器,再根据服务器提供的图片地址把图片下载下来,才能把图片在网页上呈现出来。这一来二往,起码已经费了两倍于这张图片的流量了,更别说服务器为了存储这张图片所花费的资源以及用户上传错了图片的冤枉成本(由于在html4时代,用户选择好图片后,每每只能看到图片的文件名,而没法经过预览图来进一步确认这张图片是否就是本身想要上传的)。 html5提供了新玩法,光靠浏览器,就能够对本地的(其实也能够是远程的)文件(主要是图片)进行呈现、读取、处理等操做,而这一切,则是经过html5 file api来实现的。html
首先是数据结构,html5定义了一个file对象类型来表示文件,每一个file对象对应一个文件。file对象有3个属性:name、size、type。name是不包含路径的文件名,size是以字节为单位的文件体积大小,type则是文件的MIME(例如image/jpg)。 file对象不单独存在,而是以数组形式,存在一个名为FileList的数组中。那么,如何拿到这个FileList数组呢?目前,html5有两个途径能够拿到FileList,一是经过file类型的input,二是经过拖放操做的drop事件。html5
<input id="file-input" type="file" />
复制代码
或html5新增的可进行文件多选的multiple属性:jquery
<input id="file-input" type="file" multiple />
复制代码
通常,咱们都是给input:file绑上一个onchange事件,以便在用户选定文件后,立刻进行读取文件等下一步操做:canvas
//原生js
var inputElement = document.getElementById("file-input");
inputElement.addEventListener("change", handleFiles, false);
function handleFiles() {
var fileList = this.files;
}
//jquery版
$('#file-input').on('change', function() {
var fileList = this.files;
});
复制代码
首先要设定一个可供拖放的区域:api
<div id="dropbox" style="width: 200px;height: 200px;"></div>
复制代码
另外,为了能触发drop事件,咱们必须阻止dragenter和dragover事件的默认行为:数组
var dropbox;
dropbox = document.getElementById("dropbox");
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);
function dragenter(e) {
e.stopPropagation();
e.preventDefault();
}
function dragover(e) {
e.stopPropagation();
e.preventDefault();
}
复制代码
而后,咱们就能够在drop事件的callback中,获取到fileList:浏览器
function drop(e) {
e.stopPropagation();
e.preventDefault();
var dt = e.dataTransfer;
var files = dt.files;
handleFiles(files);
}
复制代码
html5提供了两个方案:FileReader和ObjectUrl。服务器
首先须要实例化FileReader对象:数据结构
var reader = new FileReader();
复制代码
利用FileReader读取file对象是一个异步的过程,咱们须要先为FileReader设置好load事件的callback,告知FileReader在读取到file对象的数据后应该进行什么进一步的操做:异步
reader.onload = function(e) {
document.getElementById("image").src = e.target.result;
}
复制代码
上面这段代码的意思是,FileReader读取到图片的数据后,把数据(DataUrl)放到的src属性里。 最后,就是经过FileReader不一样的方法,来决定读取file对象数据后用什么数据格式来存放,并实施读取:
ObjectURL至关于文件的一个临时路径,此临时路径可随时生成、随时释放,在本地浏览器使用起来时,与普通的url无异。 以把一张本地图片显示在页面上为例:
var img = document.createElement("img");
img.src = window.URL.createObjectURL(file);
复制代码
此时,src形如:blob:http://test.local.com/e03e8bbf-66ce-4fea-a8c8-772f9fdb4d40
用这个src就能让浏览器从本地读取图片。 这种方案相对用FileReader生成图片的base64编码并放到的src里来讲,性能有了很大的提高。
比较这两种读取File对象的方案,FileReader适合用来上传文件,而ObjectURL则适合直接在浏览器进行操做,而后操做后再把处理后的数据进行上传,例如利用canvas截图或进行图片压缩等。固然,这一切都是要考虑兼容性的。