I am trying to download multiple files that the user has selected for download. However, the browser is cancelling all but last download request. If I am increasing the delay between the requests to say about 1 second, then those files get downloaded, but even in this case, sometimes some files are missed. The files are being downloaded from amazon s3 urls(i.e. these are CORS).
I am doing this by creating an anchor element with the url and then calling the click event on it using javascript.
downloadFile(url) { let a = document.createElement('a'); a.id = url; // a.setAttribute('target', 'blank'); a.download = ''; a.href = url; // firefox doesn't support `a.click()`... // console.log('dowmloading ' + url); a.dispatchEvent(new MouseEvent('click')); a.remove(); }
Then on download button click event I’m doing this:
let delay = 0; urlList.forEach(url => { return setTimeout(downloadFile.bind(null, url), 100 * ++delay); });
Is there a way to accomplish this?
Why is the browser cancelling the requests?
Advertisement
Answer
Why is the browser cancelling the requests?
Because you are essentially “canceling navigation” by clicking the next link, before the browser is fully done with what it has to do when you clicked the previous one.
If this weren’t downloads, but regular links to pages, then this is the behavior you want – if the user clicks a link to page A first, but then looses patience and clicks on another link to page B, then the request for page A gets cancelled at that point – no need in loading two resources, when only one can be displayed at the same time anyway.
I don’t think there is much you can do about this, if you do not want to figure out a “magic number” of a timeout that somehow makes it “work” – especially since you won’t know if that works in general, or maybe just on your machine, with your internet connection, etc.
I am trying to download multiple files that the user has selected for download.
You could have those selected files wrapped into a container format – like for example ZIP (more than just a “container”, strictly speaking) – dynamically on the server, so that the user just has to download one file only (which they will then have to unpack again on their own machine.)
Or you change your file selection process to begin with. Instead of having the user mark the files they want using checkboxes or something like that, present them direct links to the files instead maybe? Then they can click each one they want one after another, and the “normal” download functionality will take place.