-
Notifications
You must be signed in to change notification settings - Fork 2.3k
如何实现秒传与断点续传 #142
Comments
代码中 md5File 的调用说明,请查看这: http://fex.baidu.com/webuploader/doc/index.html#WebUploader_Uploader_md5File |
md5Blob 在ie下无法使用 有没有什么好的解决办法? |
恩,ie下确实不能用,只能扩展flash在那个里面实现。 |
filereader 已经实现在swf内了 想问下 有没有可以直接在外面用js调用读取文件的方法(不会改flash啊) |
fileReader确实可以把文件内容读取出来,但是把内容读取出来再交给JS来md5,效率肯定会很慢的。最好还是flash直接把md5值算好了把结果交给js。 以后如果这块需求比较我可以考虑加上此功能。 ps:文库那边发现可以编译c/c++版本的md5代码给flash调用,md5速度比html5的速度快出很多。但是文件读取速度html5又比flash快,所以对于一个文件读取+md5运算总体时间花费基本上差不多。 |
md5Blob 找不到Deferred方法 是依赖了什么库么 |
我直接使用的jQuery的Deferred,你没引入吗? |
好吧 哪应该写错了吧 好像是$.deferred()吧。 |
请问在IE如何获取到文件的md5码? md5Blob 在IE下报错! 找不到FileReader 对象 |
IE里面只能用flash实现,可以自己扩展flash实现md5功能,目前没有此功能。 |
也就是说IE环境下没法实现断点续传功能? 还是说有其他方法 因为本人不懂Flash! |
对,目前 IE 下无法实现断点续传,除非把 flash 版本的 md5 计算模块扩展到 webuploader 中去。 |
那请问往后的版本会考虑拓展这个功能吗? 被IE无法支持断点续传功能困扰很久了!麻烦大神能指点迷津! |
请问我在使用上述的方法进行MD5码的获取时,浏览器依旧被阻塞住了! 请问有何办法可以解决此问题! |
自 0.1.4 后 已添加 md5 模块,包括 flash 和 html5 两个实现。 |
看这个issue的意思,断点续传也是分多个请求实现的么? |
恩,基于 chunk 上传的。 |
好吧,目前有办法能在一个请求里面实现么?仅针对chrome而且,不考虑兼容新的话 |
不 chunk 的话,其实后端很难知道已经接收了多少的。像 php 都是等你的上传文件全部存入临时文件后才执行到脚本里面来。你每次接受文件,要不就是进度为0,要不进度为 100%。 |
还是我理解错你的意思了,你是不想每次 chunk 上传文件的时候都做 ajax 验证?还是压根就不想 chunk? |
@2betop md5 能停止扫描码?2G的文件,选错了,这停止都停止不掉 |
你这个妙传文件的时候,按照你的思路,先算md5,然后与服务端对比,但是如果服务端没有的话,因为你的流数据已经读过一次,不能重复再读,你怎么把数据再传到服务器。小文件可以在算md5的时候,这样数据变成byte[]数组是可以得,但是大文件肯定不行,不知道你这个大文件妙传能支持多大。或者还是有别的解决方案。 |
我是利用那个hash值来进行比对,算md5太慢了, 我自己改了三处代码 , 就能实现前端的断点续传的支持。 但现在有个新的问题,就是服务器端给我明明是有数据的, 但在uploadSuccess监听的事件中有时候却取不到服务端的值。为什么呢 ? 感觉像是在上传完成前就执行了uploadSuccess这个事件。 |
分片上传有两个问题: |
@lw394407679 webuploader是利用多线程上传, 而且上传时是没有顺序的, 所以我先将分块的文件放在一个独立的临时目录中, 当上传完成后,再进行合并。 而不是写到同一文件中(除非你将线程数改为1), |
@lw394407679 你没遇到分片上传点击暂停又继续上传,会丢失分片的情况吗? |
flash分片上传按理应该内存不会暴增因此我分为多个小片上传,为何不会释放,是不是flash问题? |
关于断点续传与秒传的总结: 这里着重说说flash的断点续传与秒传(同时也希望开发团队能够参考参考): 当文件大小在100M以下时:读取文件流然后利用spark-md5去计算出MD5是没有问题的。 那么,当文件在100M以上,甚至1G,10G,100G的时候怎么办呢?就算是HTML5模式下去计算这样的文件耗时也非常严重,有时候无法忍受了。 于是我想着能不能读取文件的开始字节+结束字节然后组合成 一个伪造的md5去进行验证呢? 可以想象一下,假设文件有351M,我以5M的区间去读取 0-5M的数据,然后346-351的数据,最终组合成一个MD5,这样在(99.9%)常规情况下,算出来的md5值也是唯一的,基本不会出现重复的。 于是我想:既然可以利用这种方式:那么应该在HTML5与Flash 下都能算出md5了,因为这样实际上我只读取了10M的内容。甚至这个值可以设置成1M一个区间,那么2M的内容算MD5,不会超过20ms。 但是:最后经过实现发现,pupload在html5时这样读取是没有任何问题,可以读取并算出md5值的,但是在flash下,超过100M文件时在读取的时候还是报错了。(这个我查阅资料说是flash fileread instance单个实例只支持100M的文件,所以读取会报错) 昨天我正在纠结这个问题的时候偶然发现国产大作 webuploader这款上传插件,于是信心满满的又开始测试了,webuploader自带md5计算方法 uploader.on('fileQueued', function (file) { 进度:" + percentage + " ")}).then(function (val) { alert('md5 result:' + val); }); $("#thelist").append(' ' + ' ');' + file.name + '' + '等待上传... ' + '}); 利用 uploader.md5File(file,start,end)方法,我们轻易可以计算出区间的md5,也可以计算完整的md5。 但是.....................在flash模式下(用ie8),又发现了相同的问题,在文件超过100m时同样计算不出md5值,并且假设文件是50g 直接 uploader.md5File(file) 与 uploader.md5File(file,0,"1mb") 所计算的耗时是一样的。 现在初步推测原因是flash的fileread instance 造成的,并且flash在读取区间数据时应该还是先把整个文件加载到内存,从内存中取得的,所以计算整个文件的md5与取一个区间是没有区别的,但是flash这块不了解,也不敢轻易改造源码。 希望webuploader开发团队能在这块上有个崭新的突破,那么做到真正的全兼容 断点续传、秒传也就不远了。 |
我感觉对文件内容做md5加密 ,不如对文件名,文件大小,文件修改时间等文件信息合并做一个hash值,这种情况发生冲突的概念也是相当小的。我做断点续传的秒传思路与原作者不同, 看了源代码:代码没有对每一块分块上传完成后的事件,若某个分块没有实际保存上,就坑了, 并且每一次分块上传都得去做ajax验证,而且skipfIle这个函数是跳过整个文件, 我做了些改造,能实现在整个文件开始上传前,我去获取已传上传完成的chunk, 然后从缺的分块开始上传,只要是上传过的分块就直接跳过。 |
楼上这种做法早在几年前用pupload试过,不适用,做出来毫无意义,打个比方用户A上传了一份SQL SERVER安装包,他电脑的时间,文件名等可能和 B用户电脑上的不相同,当B用户又上传一份SQL SERVER安装包时,你无法确定已经穿过了,做不了秒传,最多只能做针对“同一份文件”的断点续传。 |
不是毫无意义,也有一种情况用户在文件的内容后追加了一些内容, 用md5做加密, 得到的值还是不同的,实际上他们相似度可能99.99%, 所以就取决于 对“同一份文件”的定义了, 我这边的应用场景更多的是针对某一个用户的上传,他上次上传了55%,这次要接着传,我说的思路更多是“断”点“续”传,不是秒传。 |
分片上传功能已实现,但是暂停上传后再次触发上传方法时,上传进度又从0开始上传了 |
uploader.on( 'startUpload', function( file ) { |
@beyond290239 @sky20054122 |
我遇到的情况是 有分块丢失的情况, 但不清楚是因为没有发起请求,还是服务端的问题。 我也是自己在本地自测测了很多次没有复现,所以后来我在一个文件上传成功之后 ,去 上传服务器 检测一下,判断是否真正上传成功。 |
用uploader.stop(file)暂停单个文件上传后,用uploader.upload(file)无法继续上传,是怎么回事? |
14M的文件,用谷歌/火狐分片上传,好卡啊~整个上传完成差不多要五六分钟,是我哪里没有写对么?
|
@luoyehanfei @2betop @sky20054122 有其它办法解决吗? |
IE7/8/9 计算MD5还是不兼容吗? |
怎么在外部添加个文件到上传队列呢? |
@2betop 怎么在外部添加个文件到上传队列呢? |
当我切换到IE9下时,选择文件按钮失效,我在webuploader.js 源码中调用flash的位置alert了一下,发现alert没反应,而在IE10和IE11下则没问题,因此确定flash根本没有加载,对于此问题楼主有没有解决之道 |
@2betop 用了上面的HOOK的before-send上传前分段检测MD5, |
为什么我owner.md5File(file)后返回是undefined呢? |
有一个问题 服务器如何得知这个文件的md5 难道把上传目录的所有文件全部md5 一遍吗 如果有多个上传目录呢 |
@diskrooms ,肯定是前端计算所有文件MD5值,然后发送到后端,与后端计算的MD5值匹配。要比较必须要有来源和目标。 |
var fileT = uploader.getFile(parentT) Cannot read property 'file' of undefined |
@gkm1987 ,先确认var fileT = uploader.getFile(parentT)这一句有没有问题。 |
this.uploader.retry(continueFile); 我这里断网之后再连接调用upload方法或者retry并不续传,为什么? |
因为这是小众需求,所以默认没有做在webuploader里面,而只是提供hook接口,让用户很简单的扩展此功能。
那么,都有哪些重要的hook接口呢?
before-send-file
此hook在文件发送之前执行before-file
此hook在文件分片(如果没有启用分片,整个文件被当成一个分片)后,上传之前执行。after-send-file
此hook在文件所有分片都上传完后,且服务端没有错误返回后执行。对于秒传来说,其实就是文件上传前,把内容读取出来,算出md5值,然后通过ajax与服务端验证进行验证, 然后根据结果选择继续上传还是掉过上传。
像这个操作里面有两个都是异步操作,文件内容blob读取和ajax请求。所以这个
handler
必须是异步的,怎样告诉组件此handler
是异步的呢?只需要在hanlder
里面返回一个promise对象就可以了,这样webuploader就会等待此过程,监听此promise的完成事件,自动继续。以下是此思路的简单实现。
关于断点续传
其实就是秒传分片,跟秒传整个文件是一个思路。关于md5验证这块,可以ajax请求验证,也可以在文件秒传验证的时候,把已经成功的分片md5列表拿到,这样分片验证的时候就只需要本地验证就行了,减少请求数。
具体实现和思路请查看这里#139
The text was updated successfully, but these errors were encountered: