让你的网站也像Gmail一样支持文件拖放上传-HTML5之File API
如果你比较好奇,可以先从这里下载所有代码,也可以点击这里查看chrome下上传的demo,点这里查看firefox下的demo
前不久Gmail推出了支持拖拽的附件上传功能,试用了下还真不错,其实很久以前就在想能有直接拖拽附件的功能,多亏有了HTML5,Web应用越来越像客户端的应用了。
在好奇心驱使下,想了解一下Gmail到底是怎么做到的,了解了一下最新的HTML5 File API草案,这个接口主要提供的就是提供对文件对象的访问,别想歪了,这个接口是无法随意的访问系统里的文件的。他能做的就是访问<input type=”file” />标签里所选择的文件,这些文件可以通过用户手动选择,或者是HTML5的拖放接口选中的文件。有兴趣的童鞋可以看看这个规范,还算比较简单。
下面简单看看接口定义几个对象。
FileList、File对象。
在HTML5中的<input type=”file” />标签中增加了mutilple属性,允许进行多文件选择。大家应该都知道一般上传标签中是不允许选择多个文件的。 新增的这个属性就是允许进行多个文件的选择(这个在桌面应用中也很常见)。<input type=”file” multiple=”multiple” id=”file” />
下面是在Firebug中的输出
>>> var f = document.getElementById("file") >>> f.files FileList0=File length=1 // 选中的文件数量 >>> f.files[0] FilefileName=es.dll fileSize=271360 |
FileList对象就是用户选择的所有文件的对象表示,如果是通过input标签选择的,就可以通过上面代码所示的方法进行访问,File对象就可以刚才选择的某个文件的信息,如上面的代码所示,主要可以得到所选中的文件名以及文件大小信息。
你可能在想只能得到这些信息到底有什么用呢?都没有办法读取文件内容,这就得提到规范中的FileReader接口了,这个接口就是用来读取File对象文件的。
在File API规范中提到File API主要是和其他的接口协同合作。比如XMLHttpRequest (这个新接口支持通过xhr的send()方法发送File对象), DataTransfer(也就是HTML5中的拖拽接口 ), 以及Web Worksers(这个主要是异步脚本执行,相当于给JS提供了“多线程”脚本执行能力,并且支持通过postMessage()进行“线程间通信”),感兴趣的,可以看看这篇日志,以及这篇。
目前能实现这样的效果的方式主要有如下几种:
- Gmail中提到的这两个浏览器都支持拖放接口,托放以后可以直接通过托放事件的DataTransfer属性访问到本次托放是关联的文件对象列表FileList,然后通过XMLHttpRequest的send方法将File对象发送到服务器
- 在Chrome下支持直接将文件拖放到文件选择控件上,就相当于直接选择了文件。这时可以通过<input type=”file” />DOM对象的files属性访问到被托放进来的文件列表对象,然后也可以通过Ajax将文件对象发送到服务器,通过将文件选择控件透明度降低也可以实现Gmail类似的效果。 在Chrome因为可以直接通过托拽的方式让文件选择控件“赋值”,此时也可以通过一个iframe加表单的方式将数据发送到服务器。
- 在Firefox3.6下可以通过FileReader直接读取到文件的内容,然后直接将文件内容发送到服务器端(可以参考这个例子,这是个不完整的例子,直接浏览是看不到效果的,查看源代码你就会懂的。)
下面就来看看Gmail到底是怎么做到的吧。
本来想通过Firebug的概况功能来捕捉到在托拽期间的脚本执行情况,比如:
但是脚本执行里压根没有找到ajax相关的函数调用,可能是因为firebug还不支持监控页面里嵌入的iframe中的脚本执行跟踪,这也说明本次上传肯定是在某个iframe中完成的。,那就直接监听网络吧,托拽上传一个附件时查看网络情况,发现附件是通过下面的ajax post过去的:
大家注意看,是通过ajax post方式将附件POST到服务器的,
可以看出Gmail在firefox下不是通过表单直接提交实现的。在chrome下的开发人员工具有点简单,无法看到网络情况,我也懒的再去抓包看了,估计是使用透明<input type=”file” />+ajax方式实现的。
在Gmail支持托拽的声明中提到目前只支持Chrome 2+以及FireFox3.6+。虽然这两个浏览器都支持HTML5,但是对于所有规范的支持程度都是不一样的,并且规范也还不是正式规范。在Firefox3.6的release note中提到:
Support for new DOM and HTML5 specifications including the Drag & Drop API and the File API, which allow for more interactive web pages.
开始支持了HTML5的拖拽接口以及File API。
下面根据浏览器以及HTML5的规范整理出两个浏览器下实现类似Gmail 上传附件的代码。
点击这里下载所有代码,有兴趣的童鞋查看源代码就知道怎么回事了,有一定的注释:)
也可以点击这里查看chrome下上传的demo,点这里查看firefox下的demo,之所以分开是为了简单起见,当然你真的想要给你的网站提供托拽上传功能,你就得自己去同时兼容这两个浏览器啦,相信这也不是件困难的事情:)
建议继续学习:
- HTML5 离线缓存-manifest简介 (阅读:16133)
- 面向移动设备的HTML5开发框架梳理 (阅读:5998)
- JavaScript,只有你想不到 (阅读:5173)
- HTML5本地存储初探(二) (阅读:4414)
- Phonegap + HTML5 开发经验小结 (阅读:4132)
- HTML5是什么东东 我们为什么要关注 (阅读:3868)
- HTML5文件API之图片预览 (阅读:3731)
- HTML6 初探 — 你没看错,是6不是5 (阅读:3673)
- HTML5技术的调研以及贴吧应用总结 (阅读:3485)
- HTML5本地存储初探(一) (阅读:3374)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:reeze 来源: Zen Space [睿]
- 标签: HTML5
- 发布时间:2011-02-23 22:26:27
- [70] Twitter/微博客的学习摘要
- [65] find命令的一点注意事项
- [64] 如何拿下简短的域名
- [64] IOS安全–浅谈关于IOS加固的几种方法
- [63] android 开发入门
- [62] 流程管理与用户研究
- [62] Go Reflect 性能
- [60] Oracle MTS模式下 进程地址与会话信
- [59] 读书笔记-壹百度:百度十年千倍的29条法则
- [59] 图书馆的世界纪录