<style>
body {display:flex;flex-direction:column;gap:10px}
#progress {border:1px solid lightgray;padding:1px;height:20px}
#bar {background:lightblue;height:100%;width:0}
</style>
<input id=upload type=file>
<div id=progress>
<div id=bar></div>
</div>
<div id=result>ready</div>
<script>
console.clear();
var url = 'https://localhost:3010/upload';
upload.onchange = e=>{
result.textContent = 'starting upload';
bar.style.width = 0;
var file = upload.files[0];
var xhr = new XMLHttpRequest();
xhr.open('post',url);
xhr.upload.onprogress = e=>{
console.log('upload.onprogress');
console.log(e);
if(e.lengthComputable){
var p = e.loaded/e.total*100;
bar.style.width = p+'%';
}
}//onprogress
xhr.onload = ()=>{
// readyState will be 4
console.log("DONE",xhr.readyState);
bar.style.width = '100%';
result.textContent = 'done';
}//onload
xhr.send(file);
}//onchange
</script>
// upload-server.js
var {key,cert} = require('server-cert.js');
require('https').createServer({key,cert},request).listen(3010);
function request(req,res){
if(cors(req,res))return;
var f = true;
switch(req.url){
case '/' : res.end('helloworld'); break;
case '/upload' : upload(req,res); break;
default : f = false;
}//switch
if(!f){
res.end('not found');
}
}//request
function cors(req,res){
res.setHeader('access-control-allow-origin','*');
res.setHeader('access-control-allow-headers','content-type');
if(req.method!='OPTIONS'){
return;
}
res.writeHead(200);
res.end();
return true;
}//cors
function upload(req,res){
req.on('data',data=>console.log(data.length));
req.on('end',()=>{
console.log('done');
res.end('ok');
});
}//upload
<style>
body {display:flex;flex-direction:column;gap:10px}
#progress {border:1px solid lightgray;padding:1px;height:20px}
#bar {background:lightblue;height:100%;width:0}
</style>
<input id=download value=download type=button>
<div id=progress>
<div id=bar></div>
</div>
<div id=result>ready</div>
<script>
console.clear();
var url = 'https://localhost:3010/download';
download.onclick = e=>{
result.textContent = 'starting download';
bar.style.width = 0;
var xhr = new XMLHttpRequest();
xhr.open('get',url);
xhr.onprogress = e=>{
console.log('download.onprogress');
console.log(e);
if(e.lengthComputable){
var p = e.loaded/e.total*100;
bar.style.width = p+'%';
}
}//onprogress
xhr.onload = ()=>{
console.log("DONE",xhr.readyState);
bar.style.width = '100%';
result.textContent = 'done';
}//onload
xhr.send();
}//onclick
</script>
// download-server.js
var {key,cert} = require('server-cert.js');
require('https').createServer({key,cert},request).listen(3010);
function request(req,res){
if(cors(req,res))return;
var f = true;
switch(req.url){
case '/' : res.end('helloworld'); break;
case '/download' : download(req,res); break;
default : f = false;
}//switch
if(!f){
res.end('not found');
}
}//request
function cors(req,res){
res.setHeader('access-control-allow-origin','*');
res.setHeader('access-control-allow-headers','content-length');
if(req.method!='OPTIONS'){
return;
}
res.writeHead(200);
res.end();
return true;
}//cors
async function download(req,res){
res.setHeader('content-length',100);
var str = '0123456789';
for(var i=0;i<10;i++){
res.write(str);
await new Promise(res=>setTimeout(res,1000));
}//for
res.end();
}//download