利用html5 file api读取本地文件示例(如图片、PDF等)


Posted in HTML / CSS onMarch 07, 2018

在html4的年代,我们如果要在网页上呈现一张用户本地的图片,需要用户先把图片上传到服务器,再根据服务器提供的图片地址把图片下载下来,才能把图片在网页上呈现出来。这一来二往,起码已经费了两倍于这张图片的流量了,更别说服务器为了存储这张图片所花费的资源以及用户上传错了图片的冤枉成本(因为在html4时代,用户选择好图片后,往往只能看到图片的文件名,而无法通过预览图来进一步确认这张图片是否就是自己想要上传的)。

html5提供了新玩法,光靠浏览器,就可以对本地的(其实也可以是远程的)文件(主要是图片)进行呈现、读取、处理等操作,而这一切,则是通过html5 file api来实现的。
首先是数据结构,html5定义了一个file对象类型来表示文件,每个file对象对应一个文件。file对象有3个属性:name、size、type。name是不包含路径的文件名,size是以字节为单位的文件体积大小,type则是文件的MIME(例如image/jpg)。

file对象不单独存在,而是以数组形式,存在一个名为FileList的数组中。那么,如何拿到这个FileList数组呢?目前,html5有两个途径可以拿到FileList,一是通过file类型的input,二是通过拖放操作的drop事件。
通过file类型的input获取FileList

<input id="file-input" type="file" />

或html5新增的可进行文件多选的multiple属性:

<input id="file-input" type="file" multiple />

一般,我们都是给input:file绑上一个onchange事件,以便在用户选定文件后,马上进行读取文件等下一步操作:

//原生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;
});

通过拖放操作drop事件

首先要设定一个可供拖放的区域:

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

怎么读取或利用file对象呢?

html5提供了两个方案:FileReader和ObjectUrl。

使用FileReader读取file对象

首先需要实例化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对象数据后用什么数据格式来存放,并实施读取:

  1. readAsArrayBuffer(file) :读取file对象并存放为ArrayBuffer对象(ArrayBuffer对象是什么我暂时没有搞清,应该是一种为了高效存取数据而产生的数据结构)。
  2. readAsText(file [, 'UTF-8']) :以一般文本模式读取file对象,值得注意的是,利用第二个参数(可选)可指定字符编码。
  3. readAsDataURL(file) :读取file对象并存放为data: URL格式的字符串。

利用ObjectURL

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截图或进行图片压缩等。当然,这一切都是要考虑兼容性的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
CSS3中的元素过渡属性transition示例详解
Nov 30 HTML / CSS
详解HTML5中垂直上下居中的解决方案
Dec 20 HTML / CSS
HTML5中视频音频的使用详解
Jul 07 HTML / CSS
HTML5表格_动力节点Java学院整理
Jul 11 HTML / CSS
HTML5+CSS3实现无插件拖拽上传图片(支持预览与批量)
Jan 05 HTML / CSS
html5定位获取当前位置并在百度地图上显示
Aug 22 HTML / CSS
深入探究HTML5的History API
Jul 09 HTML / CSS
详解canvas绘图时遇到的跨域问题
Mar 22 HTML / CSS
AmazeUi Tree(树形结构) 应用小结
Aug 17 HTML / CSS
使用CSS3实现按钮悬停闪烁动态特效代码
Aug 30 HTML / CSS
HTML5之高度塌陷问题的解决
Jun 01 HTML / CSS
HTML 里 img 元素的 src 和 srcset 属性的区别详解
May 21 HTML / CSS
html5 分层屏幕适配的方法
Mar 16 #HTML / CSS
canvas实现图片马赛克的示例代码
Mar 26 #HTML / CSS
HTML5 拖拽批量上传文件的示例代码
Mar 28 #HTML / CSS
利用html5 canvas动态画饼状图的示例代码
Apr 02 #HTML / CSS
简单聊聊H5的pushState与replaceState的用法
Apr 03 #HTML / CSS
如何使用localstorage代替cookie实现跨域共享数据问题
Apr 18 #HTML / CSS
Html5 localStorage入门教程
Apr 26 #HTML / CSS
You might like
php通过strpos查找字符串出现位置的方法
2015/03/17 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
2019/12/20 PHP
TP5框架实现上传多张图片的方法分析
2020/03/29 PHP
javascript基础的动画教程,直观易懂
2007/01/10 Javascript
浅析JQuery获取和设置Select选项的常用方法总结
2013/07/04 Javascript
浅析jQuery中调用ajax方法时在不同浏览器中遇到的问题
2014/06/11 Javascript
javascript引用类型指针的工作方式
2015/04/13 Javascript
分享有关jQuery中animate、slide、fade等动画的连续触发、滞后反复执行的bug
2016/01/10 Javascript
nodejs 实现钉钉ISV接入的加密解密方法
2017/01/16 NodeJs
vue引入新版 vue-awesome-swiper插件填坑问题
2018/01/25 Javascript
使用Vuex实现一个笔记应用的方法
2018/03/13 Javascript
通过函数作用域和块级作用域看javascript的作用域链
2018/08/05 Javascript
解决bootstrap中下拉菜单点击后不关闭的问题
2018/08/10 Javascript
微信小程序使用wxParse解析html的实现示例
2018/08/30 Javascript
vue-cli 引入jQuery,Bootstrap,popper的方法
2018/09/03 jQuery
在webstorm开发微信小程序之使用阿里自定义字体图标的方法
2018/11/15 Javascript
纯javascript实现选择框的全选与反选功能
2019/04/08 Javascript
《javascript设计模式》学习笔记七:Javascript面向对象程序设计组合模式详解
2020/04/08 Javascript
微信小程序自定义弹出层效果
2020/05/26 Javascript
Apache如何部署django项目
2017/05/21 Python
Python基于回溯法子集树模板解决取物搭配问题实例
2017/09/02 Python
Python并发编程协程(Coroutine)之Gevent详解
2017/12/27 Python
Python3.6中Twisted模块安装的问题与解决
2019/04/15 Python
解决Python数据可视化中文部分显示方块问题
2020/05/16 Python
python爬虫scrapy框架的梨视频案例解析
2021/02/20 Python
中国高端家电购物商城:顺电
2018/03/04 全球购物
波兰最早的运动鞋精品店之一:Street Supply
2019/08/29 全球购物
Python面试题集
2012/03/08 面试题
木工主管岗位职责
2013/12/08 职场文书
旅游网创业计划书
2014/01/31 职场文书
手工社团活动方案
2014/02/17 职场文书
平安建设实施方案
2014/03/19 职场文书
有关环保的标语
2014/06/13 职场文书
机械工程及自动化专业求职信
2014/09/03 职场文书
2015年度酒店客房部工作总结
2015/05/25 职场文书
2016年五一劳动节专题校园广播稿
2015/12/17 职场文书