年初在改进公司的视频文件上传体验时接触到了SWFpload,当时的版本还没有Release,功能和文档都还在完善中,遇到了IE下的刷新BUG,可把我折腾了一番。由于手头事情太杂了,当初许诺下的“等我项目结束时希望SWFUpload放出正式版和官方确定的接口文档了,到时再针对传统文件上传的各种方式和SWFUpload功能包唠叨几句”的话,我也一直都没有实现,很是惭愧。
最近由于项目中多文件上传的需求,我才发现SWFUpload已经升级到V2.1.0版了,功能和文档都已经能够满足复杂的项目需求了,因此特把我之前的许诺补上,并附上针对V2.1.0版的SWFUpload翻译。(此版本也已经修正了IE的刷新BUG,不再需要使用我之前的解决方式了。)
一、首先来比较下目前的几种的客户端上传:
1、File表单
使用标准的HTML元素提供的File表单是最原始、传统的上传方式,他的优势在于浏览器的广泛兼容性,除了服务端需要处理Files信息以外,不需要额外的处理程序即可完成文件上传。
但使用File表单上传文件会造成页面的刷新,尤其是在上传大文件的时候,在文件上传过程中,用户需要傻等在一个空白页面前,没有任何反馈信息来提示用户当前的上传进度。同时无法在客户端对文件大小做检测。
2、IFrame结合File表单
使用一个含有file表单的iframe来完成文件上传,能够避免文件上传过程中的页面刷新,在一定程度上改进了用户体验,但同样没有解决大文件上传时候缺少反馈信息的问题。相比File表单上传,此方式还需要对程序做额外的处理,同时需要JS的支持,复杂度稍微增加了一些。
3、IFrame、File表单结合AJAX
在方式2的基础上引入AJAX来实时跟服务端脚本获取当前的上传进度,实现了页面无刷新、实时更新上传进度的功能。但程序的复杂度又增加了一个级别,由于要不断跟服务端发送请求,同时也增加了服务端的压力。
4、Activex控件
使用控件方式完成的上传在功能和效率上都很不错,页面无刷新、显示上传进度、批量上传,个人认为遗憾就在于需要在浏览器上安装控件,而且只能支持IE,弹出那么个安装提示可能会吓倒多数用户,开发的复杂度也提高了。
5、Flash
Flash的FileReference类提供了文件上传功能,相对于传统的File表单而言,Flash上传能够获取客户端的文件的更多信息反馈,例如文件大小、类型、创建、修改时间等,利用这些信息可以在客户端对文件进行类型和大小等属性的一次过滤。
FileReference类提供了多文件上传功能。
Flash直接向服务端发送文件数据,因此Flash本身是可以随时知道文件上传数据而显示上传进度,而不需要使用AJAX的方式不断跟服务端发送请求增加服务端的压力。
弊端在于客户端需要Flash播放器的支持,而且在一个页面中插入一个Flash,从UI元素的统一角度来看,似乎有些别扭,如果页面需要更改风格,那么Flash还需要重新修改然后编译,而且程序开发的复杂度也提高了。
6、Flash结合JavaScript
在方式5的基础上,将Flash隐藏起来,利用JavaScript来控制Flash元素处理文件上传,Flash使用ExternalInterface来完成跟JavaScript的通信,将页面元素的控制权交给JS。这样就避免了方式5中的UI元素不统一、修改不灵活的弊端。但代价就是Flash程序开发的复杂度再次提高了,同时也需要更高的JS和XHTML开发能力。
以上列举了目前我所了解的浏览器环境下文件上传的方式,并对其优劣都做了简单的罗列,在实际开发中我们可以根据自己的应用来选择合适的方式,假如我们的需求只是用户给自己上传一个10K不到的头像,如果我们还大费周折地实现了头像上传的进度提示,那就是事倍功半了,因为在目前的绝大多数网络情况下,一个10K的文件传输是一眨眼的功夫。