admin管理员组文章数量:1402796
I've made an XHR-based file uploader with progressbar, and I would like to add a feature to cancel the upload before it fully uploaded. The simlified code (runs after DOM ready):
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();
});
After the xhr.abort()
called, the abort event handler prints the 'aborted' to the console, but it doesn't do anything else. The progress bar doesn't stop, and after it finished, the entire file is uploaded. Tested on the latest Firefox and Chrome.
I can't figure out what is wrong with my code.
Edit:
I've tried the same with jQuery, the code: (mostly from 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();
});
To my surprise, this is working as expected. When the jqXHR.abort()
called, the 'aborted' text also printed, the process stopped, and only part of the file have been uploaded.
The problem is I want to make my code independent of jquery in the future, and I don't understand yet why my code isn't working the same way.
I've made an XHR-based file uploader with progressbar, and I would like to add a feature to cancel the upload before it fully uploaded. The simlified code (runs after DOM ready):
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();
});
After the xhr.abort()
called, the abort event handler prints the 'aborted' to the console, but it doesn't do anything else. The progress bar doesn't stop, and after it finished, the entire file is uploaded. Tested on the latest Firefox and Chrome.
I can't figure out what is wrong with my code.
Edit:
I've tried the same with jQuery, the code: (mostly from 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();
});
To my surprise, this is working as expected. When the jqXHR.abort()
called, the 'aborted' text also printed, the process stopped, and only part of the file have been uploaded.
The problem is I want to make my code independent of jquery in the future, and I don't understand yet why my code isn't working the same way.
4 Answers
Reset to default 4Ok, I noticed that the event name is onabort. With the xhr.abort = ...
line I overwrote the abort function. So the solution:
xhr.onabort = function(){...};
or
xhr.addEventListener("abort", function(){...});
I have been scouring the forums and found many solutions that fail miserably...except for Ivan Tsai's response.
The abort method will trigger error handlers on the server and the request object's abort event, but it will not stop the upload.
I have had no success stopping the upload from the server upon receiving the abort event. The following all fail:
request.pause();
request.socket.end();
request.connection.end();
request.destroy();
response.status(413).send(message);
response.end();
The only effective way I have found to stop the upload below is the HTMLFormElement.reset() method. Interestingly, calling the reset method of an input of type file will not work, but the single input can be wrapped in a singleton form element, such as the uploadForm below, to achieve the desired effect.
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();
});
You can also reload the page with window.location.reload()
or you can switch to another page with window.location.href = UrlOfNewPage
.
If this doesn't work, check if function you use to cancel the upload will be executed, for example with outputing something with console.log
I have the same problem.
XMLHttpRequest.abort()
just stop notifying XMLHttpRequest.uplad.progress
.
XMLHttpRequest.abort()
can't stop Chrome(63.0.3239.132) uploading files.
I tried the formObject.reset()
with upload 1G file and it works.
Network usage in windows task manager goes down to zero after calling formObject.reset()
.
<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>
本文标签: javascriptXHR abort doesn39t stop file uploadingStack Overflow
版权声明:本文标题:javascript - XHR abort doesn't stop file uploading - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744368580a2602906.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论