Zen Space
php erlang javascript ruby python web linux mac os x
rss
email
twitter
facebook
  • Labs
  • Resume
  • Works
  • About

Archive for 四月, 2010

让你的网站也像Gmail一样支持文件拖放上传-HTML5之File API

12 comments
Posted on 四 25 2010 by reeze

如果你比较好奇,可以先从这里下载所有代码,也可以点击这里查看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中的输出
12345>>> 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, [...]


Read More

  Tags: File API, Gmail, HTML5, 托放上传 Category: HTML5, 未分类

最近文章

  • 解决Mac下终端中使用screen管理回话但看不到滚动条等问题
  • 让你的网站也像Gmail一样支持文件拖放上传-HTML5之File API
  • 开启Mac OS X Snow Leopard的NTFS原生读写
  • 在2009的尾巴上
  • 支持IPv6的Tunnelblick For Mac OS X OpenVPN客户端

分类目录

  • G-related (1)
  • Hackintosh (1)
  • HTML5 (1)
  • JavaScript (1)
  • Mac (5)
  • PHP (5)
  • tips (1)
  • 乱78糟 (1)
  • 未分类 (5)

标签~云

2009 debug editor exception File API Gmail html HTML5 JavaScript linux Mac MacFUSE MacOSX NTFS OS X PHP screen screenrc Snow Leopard softwares ssh syntax check Tools VPN 托放上传

一些脚印

  • 张二 在 解决Mac下终端中使用screen管理回话但看不到滚动条等问题 上的评论
  • joe001 在 开启Mac OS X Snow Leopard的NTFS原生读写 上的评论
  • reeze 在 让你的网站也像Gmail一样支持文件拖放上传-HTML5之File API 上的评论
  • windy 在 让你的网站也像Gmail一样支持文件拖放上传-HTML5之File API 上的评论
  • L42y 在 Lockerz邀请 上的评论

Google Reader

    Shared Items

    日志存档

    • 2010年七月 (1)
    • 2010年四月 (1)
    • 2010年一月 (1)
    • 2009年十二月 (3)
    • 2009年十月 (2)
    • 2009年七月 (4)
    • 2009年六月 (4)

    链接表

    • Ideawu
    • LinuxToy
    • on Github
    • Tina的设计天地
    • 风雪之隅
    想读
    围城
    灿烂千阳
    The Laws of Simplicity
    结网
    蔡康永的说话之道
    正读
    建筑的永恒之道
    亲密行为
    裸猿三部曲:人类动物园
    裸猿三部曲:裸猿
    Clean Code
    读过
    我的奋斗
    无懈可击的Web设计
    应用Rails进行敏捷Web开发
    追风筝的人
    构建可扩展的Web站点

    • Resume
    • Works
    • About
    Powered by Wordpress  |  Designed by WebTreats