如何以小块上传带有ajax的文件并检查失败,重新上传失败的部分。
Posted
技术标签:
【中文标题】如何以小块上传带有ajax的文件并检查失败,重新上传失败的部分。【英文标题】:How to upload a file with ajax in small chunks and check for fails, re-upload the parts that failed. 【发布时间】:2016-02-05 21:17:10 【问题描述】:我有一个用户上传的文件,我想实现以下目标。
-
将文件分成大约一兆字节的小块。
上传每个块,等待它完成后再开始上传下一个块。
为每个块获取成功或失败报告。
重新上传失败的区块。
按百分比获取进度。
这里有一些粗略的 javascript。我真的迷路了。在线获取了一些代码并尝试对其进行修改。
$.chunky = function(file, name)
var loaded = 0;
var step = 1048576//1024*1024;
var total = file.size;
var start = 0;
var reader = new FileReader();
reader.onload = function(e)
var d = file:reader.result
$.ajax(
url:"../record/c/index.php",
type:"POST",
data:d).done(function(r)
$('.record_reply_g').html(r);
loaded += step;
$('.upload_rpogress').html((loaded/total) * 100);
if(loaded <= total)
blob = file.slice(loaded,loaded+step);
reader.readAsBinaryString(blob);
else
loaded = total;
)
;
var blob = file.slice(start,step);
reader.readAsBinaryString(blob);
我怎样才能达到上述目的。如果有可行的解决方案,请解释发生了什么。
【问题讨论】:
你试过github.com/blueimp/jQuery-File-Upload/wiki/Chunked-file-uploads 不错的开始,您需要使用累积范围进行切片,加载块大小,并且步长似乎是恒定的......一般来说,尝试将问题分解为更小的部分,就像可以从文件上传一系列数据的东西,然后是可以在文件的每个部分上调用远程上传器的部分,然后是处理错误的部分,然后是宣布“我完成了”的部分,.. . 总之,更多的小功能,少一个大的加载功能。 @dandavis 我有另一个只能做块的功能,问题是等待每个块上传。它是一个数组,每个包含大约 1mb 的块。 【参考方案1】:我已将 afzalex 的答案修改为使用readAsArrayBuffer()
,并将块作为文件上传。
var loaded = 0;
var reader = new FileReader();
var blob = file.slice(loaded, max_chunk_size);
reader.readAsArrayBuffer(blob);
reader.onload = function(e)
var fd = new FormData();
fd.append('filedata', new File([reader.result], 'filechunk'));
fd.append('loaded', loaded);
$.ajax(url,
type: "POST",
contentType: false,
data: fd,
processData: false
).done(function(r)
loaded += max_chunk_size;
if (loaded < file.size)
blob = file.slice(loaded, loaded + max_chunk_size);
reader.readAsArrayBuffer(blob);
);
;
【讨论】:
【参考方案2】:你没有为任何块上传失败做任何事情。
$.chunky = function(file, name)
var loaded = 0;
var step = 1048576//1024*1024; size of one chunk
var total = file.size; // total size of file
var start = 0; // starting position
var reader = new FileReader();
var blob = file.slice(start,step); //a single chunk in starting of step size
reader.readAsBinaryString(blob); // reading that chunk. when it read it, onload will be invoked
reader.onload = function(e)
var d = file:reader.result
$.ajax(
url:"../record/c/index.php",
type:"POST",
data:d // d is the chunk got by readAsBinaryString(...)
).done(function(r) // if 'd' is uploaded successfully then ->
$('.record_reply_g').html(r); //updating status in html view
loaded += step; //increasing loaded which is being used as start position for next chunk
$('.upload_rpogress').html((loaded/total) * 100);
if(loaded <= total) // if file is not completely uploaded
blob = file.slice(loaded,loaded+step); // getting next chunk
reader.readAsBinaryString(blob); //reading it through file reader which will call onload again. So it will happen recursively until file is completely uploaded.
else // if file is uploaded completely
loaded = total; // just changed loaded which could be used to show status.
)
;
编辑
要再次上传失败的块,您可以执行以下操作:
var totalFailures = 0;
reader.onload = function(e)
....
).done(function(r)
totalFailures = 0;
....
).fail(function(r) // if upload failed
if((totalFailure++) < 3) // atleast try 3 times to upload file even on failure
reader.readAsBinaryString(blob);
else // if file upload is failed 4th time
// show message to user that file uploading process is failed
);
【讨论】:
if(loaded 当reader.readAsBinaryString(blob)
被调用然后reader.onload
被再次调用。所以文件上传是递归进行的。
ohhhhh 好的,有道理,我们可以检查每个块的故障吗?
不是“var d = file:reader.result”,上传整个文件吗?不应该是“blob”,它是一个块吗?
var d=file:reader.result
没有上传文件。但正在读取文件,而且只是其中的一部分。以上是关于如何以小块上传带有ajax的文件并检查失败,重新上传失败的部分。的主要内容,如果未能解决你的问题,请参考以下文章