WEB 文件传输技术全讲解

导语

在WEB领域,文件上传,是一个古老的话题。对于不少网站而言,它是一个基础的功能。近些年以来,技术突飞猛进,唯独文件上传这一块却貌似依然停留在IE6的年代。对于用户来说,最不能忍受的事情,大概就是上传到99%的时候突然卡住不动然后被告知要从头开始了。因此断点续传一直是网页开发者们着力解决的技术难题。早期由于技术限制,在网页上实现断点续传的唯一途径是使用插件。直到HTML5出现以后,基于XMLHttpRequest2.0以及File API,断点续传问题才得以较好地解决。

WEB文件上传技术1.0

文件上传的最基本形式,是使用表单元素file:

<form enctype="multipart/form-data" action="upload.php" method="POST">
    <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
</form>

这种方式最简单也最直接,而且所有浏览器都支持:

选择文件后,点击Send File按钮就可以上传文件了。然而这种方式缺点也是特别明显的,首先它是“同步”上传的,也就是说,点了上传按钮后,页面就处于锁定状态。而且如果页面报错,已填写的内容可能会丢失,文件也要重新上传。

WEB文件上传技术1.1

Form表单的上传是“同步”的,有没有办法像Ajax请求那样,不刷新页面也能提交文件呢?在HTML5出现以前,只能用iframe来做到这一点。方法是,生成一个iframe,里面的内容是一个表单,当我们点击上传的时候,触发该表单进行提交,并在upload.php中返回一段js进行回调处理即可。基于这个原理实现的组件,可以参考AjaxFileUpload

该方案很好地解决了Form表单同步提交方式的不少问题,但上传的过程中无法看到进度。用户可能会等得比较焦虑,有没有方法在上传的时候看到进度条呢?

WEB文件上传技术1.2

Flash曾经是网页世界里最闪亮的一颗星星。他除了播放多媒体以外,还提供了不少底层的文件操作接口。Flash8.0以后就开始提供FileReference类,例如使用brow可以打开文件选择器选择单个文件,browForMultifiles选择多个文件, upload开始上传, load把文件内容载入内存。通过这些方法,再结合ExternalInterface方法与页面的javascript进行交互,我们就可以做成一个基于Flash的文件上传组件,常见的组件有比如, Uploadify

从上面的分析来看,Flash不仅能在上传的时候显示进度,而且一次可以选择多个文件。由于它能把文件的内容载入内容,因此理论上可以实现断点续传。然而,这种一次性把整个文件全部载入内容的方式太占用系统资源,决定了它并不适合来对大文件进行断点续传。

此外,由于Flash已经逐步退出市场,基于它来实现文件上传的组件,可能无法在iOS、Mac等设备上使用。

WEB文件上传技术2.0

实际上,在早期除了上面说的三种技术外,还有用浏览器插件来实现文件上传的,例如早期的QQ邮箱超大附件。但浏览器插件的兼容性比较差,开发维护成本也高,所以也逐步退出。

HTML5标准提出以后,网页开发者可以不借助第三方技术,只用javascript就写出支持断点续传的上传方法。所谓断点续传,就是在上传文件的时候,每次向服务器发送一小片数据,当出现中断时可以跳过已发送的部分而续传。可以看出,断点续传的重要基础是分片。HTML5的File API提供了文件的分片操作,但传统的XMLHttpRequest不支持发送二进制数据,因此还需要利用HTML5的XMLHttpRequest2.0提供的API来发送已读的文件片段(这部分片段用FormData对象封装起来)。此外,如果要实现真正意义上的断点续传,也就是当页面刷新后对同一个文件续传,还需要在前端对文件进行识别,即sha1或者md5等技术。

可见,基于HTML5实现一个断点续传的功能,可以不依赖任何第三方插件。然而,当前的PC浏览器市场里,IE浏览器,特别是不支持HTML5的IE8依然占有相当高的份额。对于这部分浏览器用户,我们不得不继续沿用FLASH来兼容。

总的来说,一个好的上传组件,除了要支持断点续传,能提供上传进度显示,支持文件多选等操作,还要兼容各种常见的浏览器,保证基本的上传功能可用。本文所介绍的上传组件——Pan Upload,基于开源组件plupload改造而成。除了支持基本的断点续传,还支持文件SHA1识别(即支持秒传、刷新页面后续传),并提供了丰富的API来支持上传进度显示,支持多文件与文件目录上传,并可以自定义文件格式过滤。对于现代浏览器,它自动启用HTML5的特性,完成快速的断点续传;对于老式的IE浏览器,它自动切换到FLASH上传方式,提供基本的上传功能。

Pan Upload的功能截图:

该组件的使用比较简单,除了传统的<script>标签引入之外,它还支持AMD方式引入,引入方法:

<script type="text/javascript" src="http://file.gad.qq.com/js/plupload.full.min.js"></script>

或者使用requirejs引入:

require(['jquery', 'http://gad.qpic.cn/assets/js/file/plupload.full.min.js?require_js=1'], function($) {
    $("#test_fileload").pan_upload_raw({
           max_file_count: 1,  //最多上传的文件数量
           multi_selection: false, //是否支持同时传多个文件
           flash_swf_url: '/assets/js/Moxie.swf', //flash地址,适配IE
           filters: {max_file_size: '10mb', mime_types: [{title: "图片", extensions: "jpg,png,gif,tif,webp"}]},  //文件大小选择与格式过滤
           events: {
                FilesAdded: function(up, files) {
                    //文件添加的回调
                }, UploadProgress: function(up, file) {
                    view.upload.percent = file.percent;
                    //文件上传进度回调
                },
                FileUploaded: function(up, file, info) {
                    //文件上传完毕回调
                    try {
                        up.disableBrowse(false);
                        view.upload.uploading = false;
                        var data = JSON.parse(info.response);
                        if (!data.success) {
                            popup.showPopup('warn','提示',"上传失败");
                        } else {
                            view.archive.cover = data.image_url;
                        }
                    } catch (e) {
                        popup.showPopup('warn','提示',"上传失败");
                    }
                },
                Error: function(up, error) {
                     //错误处理
                     popup.showPopup('warn','提示',error.message);
                }
            }
        });
});

这就完成了前端组件的引入。然而,断点续传的实现,离不开后台的支持,Pan Upload组件除了提供前台的完整支持外,在后端还提供了配套的服务:

  1. 后台支持续传、重传、秒传;
  2. 文件格式识别与处理:图片文件自动转存到CDN并提供尺寸变化(缩略图)、鉴黄、水印等服务;音视频文件自动转码并转存到CDN,提供多种画质的在线点播服务;PPT/WORD文件自动解析并提供在线预览服务等;
  3. 下载链接防盗链;
  4. 用户存储空间管理,垃圾文件定期自动回收管理等

有关后台架构的介绍,将会在另外一篇文章专门介绍。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

潘兴颂的专栏

1 篇文章1 人订阅

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏菜鸟程序员

Macos下使用加速百度云(aria2gui下载器)

5983
来自专栏沈唁志

WordPress最新版完全禁用JSON REST API输出站点信息

WordPress 从 4.4 版本开始新增的 JSON REST API 功能,通过这个 REST API 可以很轻松的获取网站的数据,可应用于其他网站、手机...

1113
来自专栏BeJavaGod

[群友分享] 第一次安装liunx系统排坑总结

本文来自群友“易水难求”总结,适合新手排坑 第一次安装设置虚拟机爬坑总结 第一坑:使用VMware Workstation 11版本的设备安装 CentOS-...

3727
来自专栏敏捷开发&项目管理

微信小程序开发 (资料汇总,谁还没被坑过?希望助你绕过一些坑)

最近帮人家做一个微信小程序,刚好想熟悉一下。由于牵扯到多用户使用系统,以及数据共享,所以自然架构选择了,客户端和服务器的方式。

1173
来自专栏web编程技术分享

Tomcat的安装配置与JavaWeb入门教程

3205
来自专栏月色的自留地

mac电脑进行可见光通信实验要点

1784
来自专栏云计算教程系列

如何在Ubuntu 14.04上保护WordPress免受XML-RPC攻击

WordPress是一个流行且功能强大的CMS(内容管理系统)平台。它的受欢迎程度可能会以专门针对WordPress网站的恶意流量形式引起不必要的关注。

90
来自专栏前端儿

移动前端页面与Chrome的远程真机调试

前几日刚入手新手机小米5,系统真心流畅呀。为啥要买小米5呢,因为要提高生产力呀,好好玩移动前端开发呀哈哈哈

903
来自专栏月色的自留地

mac电脑进行可见光通信实验要点

946
来自专栏小白课代表

Unigraphics NX 12.0安装教程

UG(Unigraphics NX)是Siemens PLM Software公司出品的一个产品工程解决方案,它为用户的产品设计及加工过程提供了数字化造型和验证...

1112

扫码关注云+社区