Use the Fetch API to download files with their original filename and the proper way to catch server errors

The Fetch API provides a handy way for downloading resources from the internet via JavaScript code. In my case I used it to download Excel sheets from the back-end of a web application. Let us check the code together and clarify things with the help of comments.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var filename = "";

// We first call fetch with the URL of the resource we want to download
fetch("https://www.example.com/")
    // This returns a promise inside of which we are checking for errors from the server. 
    // The catch promise at the end of the call does not getting called when the server returns an error. 
    // More information about the error catching can be found here: https://www.tjvantoll.com/2015/09/13/fetch-and-errors/.
    .then((result) => {
        if (!result.ok) {
            throw Error(result.statusText);
        }

        // We are reading the *Content-Disposition* header for getting the original filename given from the server
        const header = result.headers.get('Content-Disposition');
        const parts = header.split(';');
        filename = parts[1].split('=')[1].replaceAll("\"", "");

        return result.blob();
    })
    // We use the download property for triggering the download of the file from our browser. 
    // More information about the following code can be found here: https://stackoverflow.com/questions/32545632/how-can-i-download-a-file-using-window-fetch. 
    // The filename from the first promise is used as name of the file.
    .then((blob) => {
        if (blob != null) {
            var url = window.URL.createObjectURL(blob);
            var a = document.createElement('a');
            a.href = url;
            a.download = filename;
            document.body.appendChild(a);
            a.click();
            a.remove();
        }
    })
    // The catch is getting called only for client-side errors.
    // For example the throw in the first then-promise, which is the error that came from the server.
    .catch((err) =>
    {
        console.log(err);
    });
comments powered by Disqus