Open 2betop opened 10 years ago
代码中 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()吧。
对,已更新https://gist.github.com/2betop/10399507
请问在IE如何获取到文件的md5码? md5Blob 在IE下报错! 找不到FileReader 对象
IE里面只能用flash实现,可以自己扩展flash实现md5功能,目前没有此功能。
也就是说IE环境下没法实现断点续传功能? 还是说有其他方法 因为本人不懂Flash! 还有刚才在使用Hook before-file是 返回的file对象访问source时返回的是undefind 无法给分块产生MD5
对,目前 IE 下无法实现断点续传,除非把 flash 版本的 md5 计算模块扩展到 webuploader 中去。
那请问往后的版本会考虑拓展这个功能吗? 被IE无法支持断点续传功能困扰很久了!麻烦大神能指点迷津!
请问我在使用上述的方法进行MD5码的获取时,浏览器依旧被阻塞住了! 请问有何办法可以解决此问题!
自 0.1.4 后 已添加 md5 模块,包括 flash 和 html5 两个实现。
看这个issue的意思,断点续传也是分多个请求实现的么?
恩,基于 chunk 上传的。
好吧,目前有办法能在一个请求里面实现么?仅针对chrome而且,不考虑兼容新的话
不 chunk 的话,其实后端很难知道已经接收了多少的。像 php 都是等你的上传文件全部存入临时文件后才执行到脚本里面来。你每次接受文件,要不就是进度为0,要不进度为 100%。
还是我理解错你的意思了,你是不想每次 chunk 上传文件的时候都做 ajax 验证?还是压根就不想 chunk? 如果只是担心 不想 chunk的时候多发一次 ajax 验证请求的话,其实第一次就可以把当前文件所有已成功的分块 sign 取到,分块验证的时候本地验证就行了。
后端开个文件流,前端边上传边写到文件里边,然后下次重新开始的时候,先读下这个文件,然后再选择开始上传的文件offset应该就行了吧?
还有个问题想请教下,发现XHR.upload的progress事件,只有在send formData对象的时候才会正常触发,如果send一个大字符串的话,貌似就最后上传完成的时候会触发一次,不知道这是什么问题呢。
为了实现秒传,采用您在这里贴的实现代码,代码放在了webuploader.js里面,位置是在 负责文件上传 (define('widgets/upload',[…… ) 的代码片段的最后,但是运行时提示md5Blob未定义,请问采用什么方式可以调用'widgets/md5'里面的md5Blob方法? 这段秒传的实现代码应该放在什么地方
这个帖子是之前 webuploader 没有提供 md5File 时写的,现在 webuploader 有 md5File 方法了,改成采用这个方法即可,其他地方不变。
大神,我改成了md5File,依然报md5File未定义的错误。我对js的闭包不是太熟,在widgets/upload的内部,貌似是没有办法使用md5File,所以报错了。 请问这种扩展代码是不是不应该在webuploader.js里面修改啊,如果在前端页面里写这种扩展代码得话,Uploader.register 方法和 WebUploader 对象又没有定义。不知道有没有讲清楚,我是JS新手,见谅哈
已经挂到 uploader 的类上,这里你改成 owner.md5File 就行了,owner 指向 uploader 实例。
确保是用的 1.0.4+ 版本啊,之前的版本都没加这个功能。
感谢,那个未定义的错误没有了,开始上传后,出现了blob.ruid未定义的错误,(webuploader.js除了扩展了上面的代码,未做其他修改),请问这个问题是什么原因
报错信息 “Cannot read property 'ruid' of undefined ”
blob = file.source.getSource() 改成 blob = file.source; 其他问题自己慢慢看。
能请问您一下,webuploader能多实例化吗?如何做呢?
我是用java写的,后台断点之后报org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Stream ended unexpectedly,为啥
Uploader.register 您好,这个方法我在0.1.5版本上面怎么都没办法运行,用WebUploader.Uploader.register才有效,但是,hook了的事件譬如 bofore-sned-file 他不会运行。。这是何解呢?官网上面似乎有没有这个解释。
// 扩展md5逻辑
var uploader = WebUploader.Uploader;
/**
* method:before-send-file
* 在文件发送之前request,此时还没有分片(如果配置了分片的话),可以用来做文件整体md5验证。
* para:file: File对象
*/
uploader.register({
'before-send-file' : 'preupload'
}, {
preupload : function(file) {
$('#uploadBtn').attr("disabled",true);
var me = this,
owner = this.owner,
server = me.options.server,
deferred = WebUploader.Deferred(),
blob = file.source.getSource();
//var fileMd5 = file.wholeMd5;
var start = +new Date();
var $li = $('#' + file.id),
$MD5Percent = $li.find('.progress .progress-bar-info');
$li.find('span.state').text('计算MD5');
insertLog("<br>"+moment().format("YYYY-MM-DD HH:mm:ss")+" before-send-file preupload:开始计算文件("+file.name+")MD5. ");
owner.md5File( file )
.progress(function(percentage) { // 及时显示进度
var percent = parseInt(percentage * 100 ) + '%';
$MD5Percent.css('width', percent);
$MD5Percent.html(percent);
//console.log('Percentage:', percent);
})
.then(function(fileMd5) { // 完成
var end = +new Date();
// console.log("before-send-file preupload: file.size="+file.size+" file.md5="+fileMd5);
insertLog("<br>"+moment().format("YYYY-MM-DD HH:mm:ss")+" before-send-file preupload:计算文件("+file.name+")MD5完成. 耗时 " + (end - start) + '毫秒 fileMd5: ' + fileMd5);
file.wholeMd5 = fileMd5;
$.ajax({
cache : false,
type : "post",
dataType : "json",
url : baseUrl + "/fileUpload/existsMd5",
data : {
fileMd5 : fileMd5,
fileName : file.name,
isShared : $("#isShared").val()
},
success : function(result) {
$('#uploadBtn').attr("disabled",false);
me.options.formData.fileMd5 = fileMd5;
me.options.formData.isShared = $("#isShared").val();
me.options.formData.fileType = $("#fileType").val();
if (result.result) {//文件存在
insertLog("<br>"+moment().format("YYYY-MM-DD HH:mm:ss")+" before-send-file preupload:文件 "+file.name + " 已经存在,跳过上传 fileMd5:"+fileMd5);
$MD5Percent.hide();
var $li = $('#' + file.id),
$percent = $li.find('.progress .progress-bar-success');
$li.find('span.state').text('文件重复,已跳过');
$percent.css('width', 100 + '%');
owner.skipFile(file);
}else{//文件不存在
file.wholeMd5 = fileMd5;
file.chunkMd5s = result.chunkMd5s; //如果后台已经有该文件的分片记录
}
// me.data.chunksMd5 = "chunksMd5";
$('#' + file.id+' .cancleBtn').removeClass("btn-info");
$('#' + file.id+' .cancleBtn').attr("disabled",true);
deferred.resolve(true);
// return deferred.reject();
}
});
});
return deferred.promise();
}
});
@2betop 请问一下,现在的版本是否支持ie7+的断点续传
@2betop 0.1.4内置 md5 文件读取功能,支持 html5 + flash 两个运行时,ie7+中是否支持
@2betop 请问一下,断点续传的时候跳过分片怎么设置
如何实现断点续传呢?怎么设置需要上传的分片?
@wwg88888888 查看 #139 #142
@sky20054122 谢谢
@sky20054122 owner.md5File 这个能分片验证码?我在 https://github.com/fex-team/webuploader/issues/139 上只看到了整体验证md5
@wwg88888888 可以做分片验证 文档里面有
http://fex.baidu.com/webuploader/doc/index.html#WebUploader_File
md5File
md5File( file[, start[, end]] ) ⇒ promise
计算文件 md5 值,返回一个 promise 对象,可以监听 progress 进度。
uploader.on( 'fileQueued', function( file ) {
var $li = ...;
uploader.md5File( file )
// 及时显示进度
.progress(function(percentage) {
console.log('Percentage:', percentage);
})
// 完成
.then(function(val) {
console.log('md5 result:', val);
});
});
我的例子 (md5File参数传入分片文件或者传入file文件和起止字节数就是计算分片的MD5)
/**
* method:before-send
* 在分片发送之前request,可以用来做分片验证,如果此分片已经上传成功了,可返回一个rejected promise来跳过此分片上传
* para:block: 分片对象
*/
uploader.register({
'before-send' : 'checkchunk'
}, {
checkchunk : function(block) {
var me = this;
var owner = this.owner;
var deferred = $.Deferred();
var chunkFile = block.blob;
var file = block.file;
var chunk = block.chunk;
var chunks = block.chunks;
var start = block.start;
var end = block.end;
var total = block.total;
file.chunks = chunks;
insertLog("<br>"+moment().format("YYYY-MM-DD HH:mm:ss")+" before-send checkchunk:文件 "+file.name + " 分片"+chunk+"/"+chunks+"准备上传 ;");
if(chunks>1){ //文件大于chunksize 分片上传
owner.md5File(chunkFile)
.progress(function(percentage) {
//分片MD5计算可以不知道计算进度
})
.then(function(chunkMd5) {
//owner.options.formData.chunkMd5 = chunkMd5;
block.chunkMd5 = chunkMd5;
var chunkMd5s = file.chunkMd5s;
var exists = false;
if (typeof(chunkMd5s) == "undefined") {
exists = false;
} else{
exists = chunkMd5 == chunkMd5s[chunk]?true:false;
}
if (exists) {
insertLog("<br>"+moment().format("YYYY-MM-DD HH:mm:ss")+" before-send checkchunk:文件 "+file.name + " 分片"+chunk+"/"+chunks+"已经存在,跳过上传;");
deferred.reject();
} else {
deferred.resolve();
}
//console.log("before-send checkchunk:"+chunk+"/"+chunks+" chunkMd5="+chunkMd5);
});
}else{//未分片文件上传
block.chunkMd5 = file.wholeMd5;
owner.options.formData.chunkMd5 = file.wholeMd5;
deferred.resolve();
}
owner.options.formData.fileMd5 = file.wholeMd5;
return deferred.promise();
}
});
为什么我的代码register和你的最开始的是一样的,但是不管我怎么写uploader,request,他就是不触发这个对应的函数,请问这是怎么回事?
@XGHeaven
@sky20054122 在断点续传的时候,当文件的所有分片都上传完,但是使用这个方法去合并分片的时候,有问题,问题是当所有分片上传完之后,其实文件状态已经变成了uploadFinished,但实际上下面的方式还没完,没返回相应的数据 /* * * 所有分片已上传完成 * / WebUploader.Uploader.register({ 'after-send-file': 'afterSend' }, { afterSend: function( file ) { var me = this, owner = this.owner, server = me.options.server, deferred = WebUploader.Deferred();
var condition1=me.options.allowMinBreakPointResumeSize<=file.size;
var condition2=file.size>=me.options.chunkSize;
if((condition1&&condition2)){
// 与服务端验证
$.ajax(me.options.merger, {
dataType: 'json',
data: {
fileMd5: me.options.formData.fileMd5,
fileName:file.name,
fileSize:file.size
},
success: function( response ) {
if(response!=""){
/**
* 更新进度条、跳过该文件
*/
var $tr = $('#' + file.id),percentage=1,
$progressText = $tr.find('.fileSpanProgressText'),
$percent = $tr.find('.fileSpanProgressPercentage');
$progressText.html(Math.round(percentage * 100) + '%');
$percent.css('width', Math.round(percentage * 100) + '%');
percentages[ file.id ] = [file.size,1];
updateTotalProgress();
/**
* 设置成功信息
*/
var $tr = $('#' + file.id).children().eq(0);
var ret=$.parseJSON(response);
var exist=$tr.find("input").val();
if(typeof(exist)== "undefined"){
var input = "<input class='" + ret.code + "' type='hidden' value='" +response+ "'/>";
$(input).appendTo($tr);
}
}
}
});
}
}
});
问一下为什么WebUploader计算的MD5跟PHP计算出来的MD5不一样?
我打印的日志,上传顺序是对的
@XGHeaven 我后台是java计算的MD5和webuploader是一样的,可以使用第三方工具测试MD5的正确值,看看错误出在哪里。https://md5file.com/calculator (我前面分片上传到后台,java合并文件出问题,导致MD5不一样,后来修正的。你看看你的具体原因是什么)
@sky20054122 我用过第三方计算软件,发现PHP计算的是正确的,而上传的却是错误的
因为这是小众需求,所以默认没有做在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列表拿到,这样分片验证的时候就只需要本地验证就行了,减少请求数。
具体实现和思路请查看这里https://github.com/fex-team/webuploader/issues/139