2

I have a Web app created in React. Most of the URLs require authentication (Bearer). One of the API endpoints is to download a ZIP file. I'm not sure how to trigger the file to download on the clients browser. I can't do an <a> because it needs the Bearer token. The React app can download it but then how do I trigger the browser to accept the download? Thx.

Jason Leach
  • 3,889
  • 7
  • 37
  • 54

1 Answers1

3

Here is how you trigger a download:

fetch("https://yourfiledownload.api/getfile", {
        method: "POST",
        headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer XXXXXXXXXXX'
        }
    })
        .then(response => {
            const disposition = response.headers.get("content-disposition");
            filename = disposition.match(/filename=(.+)/)[1];
            return response.blob()
        })
        .then(blob => {
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = filename;
            document.body.appendChild(a); // we need to append the element to the dom -> otherwise it will not work in firefox
            a.click();
            a.remove();  //afterwards we remove the element again
            callback({msg: 'ok'})
        })

This assumes that your API sends back the right stuff including headers. So something like this in the case of a CSV file for instance:

res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
res.setHeader('Content-disposition', 'attachment; filename=' + filename);
res.set('Content-Type', 'text/csv');

res.write("Some Data here");
res.end();

Note that Content-Disposition is needed so that the filename is determined by your API and sent back to the client.

codemonkey
  • 7,325
  • 5
  • 22
  • 36