6

I am sending a zip file from my nodejs server to the browser using the following

res.set("Content-Type", "application/octet-stream");
res.set("Content-disposition", `attachment; filename="`+zip_name+`.zip"`);
res.set("Content-Length", zipBuff.length);
res.send(zipBuff);

I am then fetching it by using :

fetch("/my/url", {
    method: "POST",
    body: formData,
})
    .then(response => {
        return response.blob();
    })
    .then(response => {
        const blob = new Blob([response], {type: 'application/zip'});
        const downloadUrl = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = downloadUrl;
        a.download = "blah.zip";
        document.body.appendChild(a);
        a.click();
    });

I would like to be able to use zip_name instead of blah for the filename but I can't figure out how to access the headers (in that case Content-disposition) of the response with fetch.

Could someone please explain how it's done ?

2 Answers 2

6

In the first promise arrow function you have access to the HTTP response headers. If you update it to return the promise from the blob function call. Then in this nested function you can return an object that includes the header value to the outer second arrow function that processes the blob data.

Updated fetch example that includes processing the Promise returned from blob-function call.

fetch("/my/url", {
    method: "POST",
    body: formData,
})
    .then(response => {
       return response.blob().then((data) => {
          return {
            data: data,
            filename: response.headers.get('Content-disposition'),
          };
       });
    })
    .then(({ data, filename }) => {
        const blob = new Blob([data], { type: 'application/zip' });
        const downloadUrl = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = downloadUrl;
        a.download = filename.split('=')[1];
        document.body.appendChild(a);
        a.click();
    });

Thank you Chapo for pointing out the issue with my previous example

Sign up to request clarification or add additional context in comments.

1 Comment

response.blob() is itself a promise so the above won't work : stackoverflow.com/questions/66105336/…
5

Return blob and headers in object

fetch("/my/url", {
    method: "POST",
    body: formData,
})
    .then(response => {
        const headers = response.headers
        return { blob: response.blob(), headers }
    })
    .then(({blob, headers}) => {
        /// now you can access to **headers** and blob data
    });

UPD:

To access the headers use headers.get("Header name").split('=').pop()

UPD1:

const foo = async () => {
    const response = await fetch("/my/url", {
        method: "POST",
        body: formData,
    })
    if(!response.ok)
        thorw new Error("Some error happend")

    const blod_data = await response.blob()
    const header_with_name = response.headers.get("Header name").split('=').pop()
    // do something with it
}

4 Comments

Thanks this is useful. Interestingly when I use this method, my zip file becomes invalid. The only thing I've changed is this specific thing (and pointing to the right place in the next bit of code of course). Any ideas ?
in fact you should take into account the fact that response.blob() is itself a promise. the above won't work.
then try async await functions

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.