XHR 中止不会停止文件上传
Posted
技术标签:
【中文标题】XHR 中止不会停止文件上传【英文标题】:XHR abort doesn't stop file uploading 【发布时间】: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,但我还不明白为什么我的代码不能以同样的方式工作。
【问题讨论】:
【参考方案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>
【讨论】:
以上是关于XHR 中止不会停止文件上传的主要内容,如果未能解决你的问题,请参考以下文章