【问题标题】:XHR abort doesn't stop file uploadingXHR 中止不会停止文件上传
【发布时间】:2016-06-03 17:19:13
【问题描述】:

我已经制作了一个带有进度条的基于 XHR 的文件上传器,我想添加一个功能以在完全上传之前取消上传。 简化的代码(在 DOM 准备好后运行):

var xhr;

$('#upload').click(function(){
    var file = $('#file').get(0).files[0];
    xhr = new XMLHttpRequest();
    xhr.upload.onprogress = function(event){
        if (event.lengthComputable){
            var percent = event.loaded / event.total;
            $('#uploadpercent').html(Math.round(percent * 100) + "%");
        }
    };
    xhr.abort = function(){
        console.log('aborted');
    };
    xhr.onload = function(){
        $('#uploadpercent').html("100%");
        // ...
    };
    xhr.open("POST", "upload.php?filename=" + file.name);
    xhr.send(file);
});

$('#cancel').click(function(){
    xhr.abort();
});

在调用xhr.abort() 之后,中止事件处理程序将“中止”打印到控制台,但它不执行任何其他操作。进度条没有停止,完成后,整个文件被上传。在最新的 Firefox 和 Chrome 上测试。

我无法弄清楚我的代码有什么问题。

编辑:

我用 jQuery 也试过了,代码: (主要来自How can I upload files asynchronously?

var jqXHR;

$('#upload').click(function(){
    var file = $('#file').get(0).files[0];
    jqXHR = $.ajax({
        type : "POST",
        url : "upload.php?filename=" + file.name,
        data : file,
        xhr: function(){
            var myXhr = $.ajaxSettings.xhr();
            if (myXhr.upload){
                myXhr.upload.addEventListener('progress', function(event){
                    if (event.lengthComputable){
                        var percent = event.loaded / event.total;
                        $('#uploadpercent').html(Math.round(percent * 100) + "%");
                    }
                }, false);
            }
            return myXhr;
        },
        success : function(response){
            $('#uploadpercent').html("100%");
            if (response.length > 0){
                console.log(response);
            }
        },
        error : function(_jqXHR, textStatus){
            if (textStatus === "abort"){
                console.log('aborted');
            }
        },
        cache : false,
        contentType : false,
        processData : false
    });
});

$('#cancel').click(function(){
    jqXHR.abort();
});

令我惊讶的是,这按预期工作。当jqXHR.abort() 被调用时,'aborted' 文本也被打印出来,进程停止,并且只有部分文件被上传。 问题是我想让我的代码在未来独立于 jquery,但我还不明白为什么我的代码不能以同样的方式工作。

【问题讨论】:

    标签: javascript file-upload xmlhttprequest abort


    【解决方案1】:

    好的,我注意到事件名称是 onabort。使用xhr.abort = ... 行我覆盖了中止功能。所以解决方案:

    xhr.onabort = function(){...};

    xhr.addEventListener("abort", function(){...});

    【讨论】:

      【解决方案2】:

      我一直在搜索论坛,发现许多解决方案都失败了......除了 Ivan Tsai 的回应。

      abort 方法将触发服务器上的错误处理程序和请求对象的 abort 事件,但不会停止上传。

      在收到中止事件后,我没有成功停止从服务器上传。以下全部失败:

      request.pause();
      request.socket.end();
      request.connection.end();
      request.destroy();
      
      response.status(413).send(message);
      response.end();
      

      我发现停止上传的唯一有效方法是 HTMLFormElement.reset() 方法。有趣的是,调用file类型的input的reset方法是行不通的,但是可以将单个input包裹在一个单例的表单元素中,比如下面的uploadForm,来达到想要的效果。

      var formData = new FormData(uploadForm),
          files = fileInput.files,
          xhr;
      
      if(files) {
         for (var i = 0, stop = files.length; i < stop; i++) {
             formData.append(files[i].name, files[i]);
         }
      
         xhr = new XMLHttpRequest();
         xhr.open('POST', uploadForm.getAttribute('action'), true);
         progressListener = xhr.upload.addEventListener("progress", progressHandler, true);
         xhr.upload.addEventListener("abort", abortHandler, true);
         xhr.send(formData);
      }
      
      abortButton.addEventListener(function(){
          if(xhr){
              xhr.abort();
          }
          uploadForm.reset();
      });
      

      【讨论】:

      • 这确实有效,谢谢。我使用 document.createElement('form') 传递给 FormData 对象,并在该表单上调用了重置。
      【解决方案3】:

      您也可以使用window.location.reload() 重新加载页面,或者您可以使用window.location.href = UrlOfNewPage 切换到另一个页面。

      如果这不起作用,请检查您用于取消上传的函数是否会被执行,例如输出带有console.log的内容

      【讨论】:

        【解决方案4】:

        我也有同样的问题。

        XMLHttpRequest.abort() 停止通知XMLHttpRequest.uplad.progress

        XMLHttpRequest.abort() 无法阻止 Chrome(63.0.3239.132) 上传文件。

        我尝试了formObject.reset()上传1G文件,它可以工作。

        在调用formObject.reset() 后,Windows 任务管理器中的网络使用率降至零。

        <script>
        function cancelUploadFile() {
          document.getElementById("my_form").reset();
        }
        </script>
        
        <form id="my_form" method="post" enctype="multipart/form-data">
          <div class="w3-grey"  style="height:24px;width:0%" hidden 
        id="progressBar"></div>
          <input type="file" id="file1" name="file1">
          <input type="submit" value="Upload" onclick="uploadFile()">
          <input type="submit" value="Cancel" onclick="cancelUploadFile()">
        </form>

        【讨论】:

          猜你喜欢
          • 2012-06-16
          • 1970-01-01
          • 2016-02-27
          • 2013-11-12
          • 2014-08-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多