8

I am trying to use XHR to track uploading progress, but at my onprogress callback at event.total I only getting Content-Length from response header instead of uploading file size:

xhr.onprogress = (event) => {
  console.log('Progress ' + event.loaded + '/' + event.total);
}

I use Multer to handle file uploading and seems it is not avaible to handle file uploading by default: https://github.com/expressjs/multer/issues/243

So I tried to handle uploading with progress-stream:

  var p = progress({ time: 1 });
  request.pipe(p);

  p.on('progress', function() {
    console.log('Progress...');
  });

But it works same way, I only get onle "Progress..." at log and at XHR onprogress event.total I have only Content-Length value instead of file size value. Help please, I have no idea how to fix it!

user1341315
  • 115
  • 1
  • 8

1 Answers1

21

You don't need get the progress in the backend if you want to show the progress, you only need to know what you've sent from your frontend to backend so you can calculate the upload progress.

In your frontend .js or .html, try something like this:

var formData = new FormData();
var file = document.getElementById('myFile').files[0];
formData.append('myFile', file);
var xhr = new XMLHttpRequest();

// your url upload
xhr.open('post', '/urluploadhere', true);

xhr.upload.onprogress = function(e) {
  if (e.lengthComputable) {
    var percentage = (e.loaded / e.total) * 100;
    console.log(percentage + "%");
  }
};

xhr.onerror = function(e) {
  console.log('Error');
  console.log(e);
};
xhr.onload = function() {
  console.log(this.statusText);
};

xhr.send(formData);

In the backend you only need a simple endpoint like this:

app.post('/urluploadhere', function(req, res) {
  if(req.files.myFile) {
    console.log('hey, Im a file and Im here!!');
  } else {
    console.log('ooppss, may be you are running the IE 6 :(');
  }
  res.end();
});

Multer is also necessary and remember, xhr only works in modern browsers.

danilodeveloper
  • 3,840
  • 2
  • 36
  • 56
  • 1
    I'm so blind. I have been thinking that I needed to attach the `progress` listener to the `XMLHttpRequest`. You actually need to attach it to the `upload` property of the `XMLHttpRequest`. Everything worked after that. Thanks. – zero298 Dec 15 '17 at 23:15
  • 1
    This monitors what the client-side upload progress. How does it work if I want to montor the upload progress of the data as it is received in the server-side? – libzz Nov 21 '19 at 06:17
  • @libzz You ever found the answer to that? I'm on react-expressjs-multerS3 stack – kyw Dec 15 '19 at 05:56
  • @kyw, I found something [here](https://stackoverflow.com/a/37938873/1276980) but nothing further. I gave up and eventually ended up using the same way in this question's accepted answer . – libzz Dec 17 '19 at 05:14
  • yea i saw that answer too :) I believe even if I could pull that off, I'd still need like a web socket to push the progress percentage to front-end. Thanks for getting back anyway @libzz ! – kyw Dec 17 '19 at 05:32