[FEATURE] Announce total length in HTTP header 'Content-Length'
See original GitHub issueThank you for your library. I was wondering if it is possible to calculate the download progress as a percentage. To do this, the response object of downloadZip()
would have to contain the HTTP header Content-Length
, which it does not at the moment.
I have already found that browsers hide HTTP headers from scripts on cross-origin requests (see here) unless the HTTP header Access-Control-Expose-Headers
says otherwise. So, I adapted my server config to expose the Content-Length
header. As a result, the request to fetch my test file returns the HTTP header Content-Length
(see (1) in code snippet). But, because the HTTP header Content-Length
is still missing on the response of downloadZip()
(see (2) in code snippet), I cannot calculate a progress in percent (as the absolute value is unknown).
So my question is: is it even possible to include the HTTP header Content-Length
and have it contain the sum of all content lengths of the files to be downloaded?
The following code snippet demonstrates how to observe the download progress:
import { downloadZip } from 'https://cdn.jsdelivr.net/npm/client-zip/index.js';
async function download() {
/// (1) Original HTTP request where the Content-Length header is present
const file = await fetch('https://4sc35swexhjkk3fe-public.s3-eu-west-1.amazonaws.com/elevator-music.mp3');
const response = await downloadZip([file]);
const reader = response.body.getReader();
/// (2) Content-Length header is missing -> always 0 -> cannot calculate a relative progress
const contentLength = +response.headers.get('Content-Length');
let receivedLength = 0;
const chunks = [];
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
chunks.push(value);
receivedLength += value.length;
console.log(`Received ${receivedLength} of ${contentLength}`);
}
const blob = new Blob(chunks);
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = 'test.zip';
link.click();
link.remove();
}
download();
Issue Analytics
- State:
- Created 3 years ago
- Comments:16 (8 by maintainers)
Top GitHub Comments
Hello. As I have explained in CONTRIBUTING.md,
downloadZip
does not set the content-length because it doesn’t know it when it returns the Response (at that point, it hasn’t even started to read the inputs). That is a consequence of the streaming design of the library.It would be possible to set content-length without sacrificing memory efficiency if
fetch
every input first (without reading the data)Is that OK for you ?
Then of course
downloadZip
needs some new code to detect that every length is known in advance and to take advantage of it.Should be solved with the newly published versions 1.5 (still distributed as ES2018 and without Zip64) and 2.2.
I must say the feature came at a significant cost in kilobytes (well, only about 1kB, but client-zip being so small to begin with, that was a big increase).