我正在实现一个文件上传拆分器,使用 FileReader API 将上传的文件分成多个部分,并将其以单独的 ajax 请求发送到后端。
不知何故,我的文件部分使用以下模式多次上传:
1) 切片 0
2) 切片 0,1
3) 切片 0,1,2
对于较大的文件,当达到一定数量的并行上传时,这通常会导致浏览器崩溃。
我想一次上传一个片段,然后再可能测试并行指定定义数量的片段是否会带来任何性能优势。
代码如下:
function startFileUpload() {
if (jQuery('#upload').length) {
var reader = {};
var file = {};
var slice_size = 4000 * 1024;
var size_done = 0;
var percent_done;
reader = new FileReader();
file = document.querySelector('#upload').files[0];
upload_file(0);
function upload_file(start) {
var next_slice = start + slice_size + 1;
var blob = file.slice(start, next_slice);
reader.readAsDataURL(blob);
reader.addEventListener("loadend", function () {
/*reader.onload = function (event) {*/
if (event.target.readyState !== FileReader.DONE) {
return;
}
// At this point the file data is loaded to event.target.result
jQuery.ajax({
url: 'https://jvdgj5oln9.execute-api.us-east-2.amazonaws.com/Prod/upload',
type: 'POST',
dataType: 'json',
cache: false,
crossDomain: true,
data: {
action: 'upload',
slice_no: (next_slice-1)/slice_size+1,
file_data: event.target.result,
file: file.name,
file_type: file.type
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR, textStatus, errorThrown);
},
success: function (data) {
if (size_done < start + slice_size){
size_done = start + slice_size; //<!--- comment 1
percent_done = Math.floor((size_done / file.size) * 100);
if (next_slice < file.size) {
// Update upload progress
jQuery('#upload_progress').html('Uploading File - ' + percent_done + '%');
// More to upload, call function recursively
upload_file(next_slice);
} else {
// Update upload progress
jQuery('#upload_progress').html('Upload Complete!');
}
}
}
});
});
}
}
}
我已使用 Chrome 调试器检查过 startUpload 仅被调用一次。
我还使用调试器检查了“注释 1”处的代码在每个切片中不会被调用多次,但是我可以看到 ajax 请求是通过 1、然后 2、然后 3 个切片并行触发的网络选项卡。
我也看不到任何自动执行的 JavaScript 闭包?所以我不清楚哪个部分会多次触发。
最佳答案
每次调用 upload_file()
时,都会将一个新的事件监听器连接到 reader.loadend
事件。
由于 reader
是在 upload_file()
范围之外定义的,因此您最终会在同一对象上得到一堆事件监听器。
在 startFileUpload()
中连接事件监听器,或者将 reader
移动到 upload_file()
范围。
关于javascript - FileReader > ajax 触发两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58228996/