0

My website has some documents that are only "download-able" if they are logged in. So when an anchor element gets clicked, it needs to append the authorization header, then the API returns the blob. In order to add the authorization header, I used the solution where I replace the href on the anchor element with a click event. Here's that code:

Html

<a class="{{ anchorClasses }}" (click)="!downloadDocument(path)" href="">
    <i *ngIf="iconClasses && iconClasses.length > 0" class="{{ iconClasses }}" aria-hidden="true"></i><span [innerHTML]="linkText"></span>
</a>

Typescript code

downloadDocument(url: string) {
    this.appDataService.spinnerService.show();

    return this.anchorDocumentService.downloadDocument(url)
        .subscribe((result: any) => {
            this.downloadFileFromBlob(result, url);

            return false;
        }, (error: any) => {
            console.error(error);

            this.appDataService.spinnerService.hide();
            this.appDataService.routeToErrorPage(error);

            return false;
        });
}

As you'll see in the subscribe's function success callback, I immediately call the "downloadFileFromBlob" function, here's that:

private downloadFileFromBlob(blob: any, url?: string) {
    console.log('DownloadLinkComponent | downloadFileFromBlob...');

    try {
        const anchorDownloadUrl = window.URL.createObjectURL(blob);
        const anchorDownload = document.createElement('a');

        document.body.appendChild(anchorDownload);

        anchorDownload.href = anchorDownloadUrl;

        anchorDownload.setAttribute('style', 'display: none;');
        anchorDownload.setAttribute('target', '_blank');

        if (url && url.length > 0) {
            anchorDownload.setAttribute('download', this.isDocumentService.getFilenameFromPath(url));
        }

        console.log('DownloadLinkComponent | downloadFileFromBlob | clicking the hidden download link...');
        anchorDownload.click();
        // anchorDownload.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }));

        window.URL.revokeObjectURL(anchorDownloadUrl);
    } catch (error) {
        this.appDataService.routeToErrorPage(error);
    } finally {
        this.appDataService.spinnerService.hide();
    }
}

So, in chrome, this works great. But in IE, it's throwing an error on this line:

anchorDownload.click();

In IE, the error page that is displayed says:

The webpage cannot be displayed

 Most likely cause: •Some content or files on this webpage require a program that you don't have installed.

Here's where I got the code to add the auth header: How to set a header for a HTTP GET request, and trigger file download?

So, in chrome when that click event fires, it downloads the blob to my local file system, and the url, aka filepath for that file is what is set as the href for the [hidden] anchor click event. So....why is IE not able to download this file?

ganders
  • 7,285
  • 17
  • 66
  • 114

1 Answers1

0

I'm not sure if this should be closed, or just a link to the answer...so here's a link to the answer that I found:

blob download not working in IE

The fix for this is just two lines of code:

if (navigator.appVersion.toString().indexOf('.NET') > 0)
        window.navigator.msSaveBlob(blob, filename);
else
        const anchorDownloadUrl = window.URL.createObjectURL(blob);
        const anchorDownload = document.createElement('a');
        // ... the rest of the code in the 'downloadFileFromBlog' function

So, just a quick check to see if we are running in IE, if so, just call the save function.

ganders
  • 7,285
  • 17
  • 66
  • 114