javascript - FileReader > ajax 触发两次

标签 javascript jquery ajax filereader

我正在实现一个文件上传拆分器,使用 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/

相关文章:

javascript - 将 Babel 添加到 HTML

javascript - 预加载图像并具有缓冲区符号

javascript - 如何在相扑选择下拉列表中显示ajax响应?

javascript - 加载选项列表一次并将其渲染到客户端的多个选择框?

javascript - JQuery AJAX POST 在 Liberty 配置文件上的 HttpServletRequest 中生成 null 参数

javascript - 401 未经授权的问题

javascript - 单击 td 时更改 bgcolor?

php - 如何将 html 和 php 代码存储在 php 变量中以回显到 html 页面

javascript - 动态添加和删除 CSS

javascript - 关闭当前模态后打开新模态( Bootstrap )