循环中来自 xhr 的多个 onprogress 事件处理程序

Multiple onprogress event handlers from xhr in loop

我目前正在尝试构建一个 ajax 图片上传器,除了一个重要部分外,我可以正常工作。

对于我上传的每个单独的文件,我想更新该文件的进度条。目前它只更新最后一个文件的进度条。

       $("#upload-btn").click(function() {
            console.log("Click");

            for (var i = 0; i < files.length; i++) {
                var fd = new FormData();
                fd.append("file", files[i]);
                fd.append("__RequestVerificationToken", $("input[name='__RequestVerificationToken']").val());

                var xhr = new XMLHttpRequest();
                xhr.open('POST', "@Url.Action("AjaxUpload")", true);

                var filename = files[i].name;

                xhr.upload.onprogress = function (e) {
                    if (e.lengthComputable) {
                        var percentComplete = (e.loaded / e.total) * 100;
                        console.log(percentComplete + '% uploaded');

                        var progressbar = $('a[data-name="' + files[i].name + '"]').siblings(".progress").find(".progress-bar");
                        progressbar.css("width", percentComplete + "%");
                    }
                };

                xhr.onload = function () {
                    console.log(this.status);
                    if (this.status == 200) {
                        var resp = JSON.parse(this.response);
                        console.log('Server got:', resp);
                    };
                };

                xhr.send(fd);
            }
        }); 

您可能已经从代码中猜到了,我在 javascript 方面非常糟糕...非常感谢您的帮助。

您需要在进度回调中限定文件名的范围,目前它只会使用 i 的最后一个值。用此代码替换您设置 onprogress 处理程序的位置。

(function(filename) {
    xhr.upload.onprogress = function (e) {
        if (e.lengthComputable) {
           var percentComplete = (e.loaded / e.total) * 100;
           console.log(percentComplete + '% uploaded');

           var progressbar = $('a[data-name="' + filename + '"]').siblings(".progress").find(".progress-bar");
           progressbar.css("width", percentComplete + "%");
        }
    };
})(files[i].name);

你可以这样做。设置xhr.upload

的附加参数
// Set custom properties
xhr.upload.targetFileName = fileName;

然后像这样在进程处理程序中访问它

xhr.upload.onprogress = function (e) {
   
   // Access custom properties. 
   var fileName = e.target.targetFileName;
}

此处有更多详细信息:https://hacks.mozilla.org/2009/06/xhr-progress-and-richer-file-uploading-feedback/ view-source:http://mozilla.pettay.fi/xhr_upload/xhr_file_upload_demo_with_speed.html