This shows how you can leverage a ServiceWorker to stream without ever having to store a full Blob of the ZIP in the browser.
I'm doing it here by POSTing a simple form with an arbitrary number of URL fields (therefore no JavaScript is needed to send the list — no onsubmit — but only to register the ServiceWorker and clone the URL input). You could also use hidden fields to specify some extra URLs or headers, even specify all the URLs that way to make a non-interactive form with only a submit button visible.
The ServiceWorker (just 14 lines) intercepts the request, lazily fetches the URLs found in the form data
(all the fields named "url") with a DownloadStream,
feeds that to downloadZip
and responds with downloadZip
's return value (which is a Response).
That's it.
The process is only a bit more complicated that using a Blob (look at the code).