Bug 277286

Summary: XHR Upload Progress Even Fires Erratic/Randomly on Slow Connections
Product: WebKit Reporter: Donovan <donovan>
Component: DOMAssignee: Nobody <webkit-unassigned>
Status: NEW ---    
Severity: Major CC: achristensen, annevk, cdumez, fred, webkit-bug-importer, youennf
Priority: P2 Keywords: InRadar
Version: Safari 17   
Hardware: All   
OS: All   

Description Donovan 2024-07-29 14:57:12 PDT
When doing a POST file upload using "new XMLHttpRequest()" progress is not fired at any consistent interval. When you do a upload the progress jumps to a high % and will randomly fire at large intervals. If you have a slow connection it will seem as if progress is not being made because it may go instantly to 7% then to 15% then 25% and so on. With a large file, the events are fired in a long interval between. 

This is mostly observed with a slow connection. If you use "Network Link Conditioner" includes with "Additional xCode Tools" Slow your connection to 10 Mbps download and 1 mbps upload. Then use the sample code below and upload a large-size file and you will see progress inside webkit/safari does not fire at any set interval allowing for smooth progress. If you use the same code in FireFox or another non webkit browser the progress event is fired correctly allowing for smooth progress and updated upload information. 


SAMPLE CODE: 


<!DOCTYPE html>
<html>
<head>
<script>
function _(el){
	return document.getElementById(el);
}
function uploadFile(){
	var file = _("file1").files[0];
	// alert(file.name+" | "+file.size+" | "+file.type);
	var formdata = new FormData();
	formdata.append("file1", file);
	var ajax = new XMLHttpRequest();
	ajax.upload.addEventListener("progress", progressHandler, false);
	ajax.addEventListener("load", completeHandler, false);
	ajax.addEventListener("error", errorHandler, false);
	ajax.addEventListener("abort", abortHandler, false);
	ajax.open("POST", "https://httpbin.org/post");
	ajax.send(formdata);
}
function progressHandler(event){
	_("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total;
	var percent = (event.loaded / event.total) * 100;
	_("progressBar").value = Math.round(percent);
	_("status").innerHTML = Math.round(percent)+"% uploaded... please wait";
}
function completeHandler(event){
	_("status").innerHTML = event.target.responseText;
	_("progressBar").value = 0;
}
function errorHandler(event){
	_("status").innerHTML = "Upload Failed";
}
function abortHandler(event){
	_("status").innerHTML = "Upload Aborted";
}
</script>
</head>
<body>
<h2>HTML5 File Upload Progress Bar Tutorial</h2>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <input type="file" name="file1" id="file1" onchange="uploadFile()" ><br>
  <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
  <h3 id="status"></h3>
  <p id="loaded_n_total"></p>
</form>
</body>
</html>
Comment 1 Radar WebKit Bug Importer 2024-08-05 14:58:14 PDT
<rdar://problem/133245878>
Comment 2 Fred S 2024-09-22 07:03:11 PDT
I have the same issue on WebKit iOS 18.

totalSize is completely off until it is complete, then changes to the correct value:

total: 18446744073709552000
totalSize: 18446744073709552000

Last progress event returns the correct values:

total: 59461221
totalSize: 59461221