Chapo
Chapo

Reputation: 2543

Access Headers when using fetch in javascript

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 ?

Upvotes: 6

Views: 7093

Answers (2)

marcusholmgren
marcusholmgren

Reputation: 134

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

Upvotes: 5

Levaya Pochta
Levaya Pochta

Reputation: 199

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
}

Upvotes: 5

Related Questions