Multi-File-Download using JavaScript
“Please create a ZIP for us, so we can download with 1 click.” — I think nearly every developer has heard something like this a lot of times.
But times change and we do not have the resources to shift files with multiple GB of data within applications and there are even more architecture guidelines (especially on prem) telling us where to store the files and how to access them. (We are not using S3 on prem — this would simplify it a lot)
How to handle it?
We can go for various Front-End plugins or try to use Download managers, but most of the time this will need additional components and installations.
I tried to use the straight forward way and I want to show the limitations.
First of all here you can find the project to try on your own: https://github.com/robertdiers/js-multi-file-download
Limitations:
- Browser may warn you because of multiple files getting downloaded from one page
- Downloads will ask for the target folder each time, when feature is activated
- Keep an eye on CORS regulations
#1 Multi-File-Download using native JS
I have found a cool and simple script enabling us to download an array of files in parallel: https://github.com/robertdiers/js-multi-file-download/blob/master/src/main/resources/static/multidownload.js
It works great with small files, for example images. But when I try to download larger files (like 500MB) it sometimes skips a few of them without giving a reason or error message. (Google Chrome)
#2 Multi-File-Download using FileSaver project
I have used it really often, but now we have to try with multiple files: https://github.com/eligrey/FileSaver.js/
Having a list of URLs (filename und download-url) you can start the downloads using the fetch command:
urls.forEach(function (e) {
fetch(e.download)
.then(res => res.blob())
.then(blob => {
saveAs(blob, e.filename);
});
});
This will download the files in parallel, Google Chrome is doing this with a defined amount of files. I have now idea how it sets this number, as it differs from execution to execution. But it works.
Be careful, this code will start to download the file to your Browser and than sending it to your disc.
#3 StreamSaver.js
The new one: https://github.com/jimmywarting/StreamSaver.js
I’m working in a highly regulated environment without Internet access and I’m afraid this will not work out of the box or may required approvals…
So StreamSaver creates a own man in the middle that installs the service worker in a secure context hosted on github static pages. either from a iframe (in secure context) or a new popup if your page is insecure.
To be honest — I haven’t investigated more because of this. Feel free to give your experiences with this one in the comments if you like to :-)
EDIT 2022–07–21
#4 using a mix of named approaches:
Open a new tab for the downloads (as Browser will use dedicated memory for this), but execute all downloads sequentially after each other with FileSaver.js (will do it one-by-one without overloading the backend).
- Browser does not handle download list anymore — no unexpected failures (will be done by the new JS in new tab)
- Download throttling could be implemented
To be honest I haven’t tried the last one— but let me know in comments how you solved it :-)