0

In my angular 7 application I have an API, when called, will download a PDF.

Here is my methods for getting the PDF:

getPdf() {
  const payload = { applicantId: this.idHeader, codes: 
  this.codeHeader + ':0', genderType: this.gender, data: this.data }

  this.service.getPdfConfirmationView(payload).subscribe((pdfResponse: 
  any) => {
    let dataType = 'application/pdf';
    let binaryData = [];
    binaryData.push(pdfResponse);
    let downloadLink = document.createElement('a');
    downloadLink.href = window.URL.createObjectURL(new Blob(binaryData, { type: dataType }));
    if (pdfResponse)
      downloadLink.setAttribute('download', 'ConfirmationReport');
    document.body.appendChild(downloadLink);
    downloadLink.click();
    })
  }

Here is my service for connecting to the API

  getPdfConfirmationView(payload) {
    return this.http.get(environment.apiUrl + 
    '/v1/report/getPdfConfirmationView',
    { headers: this.getSearchApiHeaders(payload), responseType: 'blob' });
  }

This works fine in Chrome browsers, I'm able to click on the link and download a PDF file to my computer. However, in Internet Explorer 11, I am getting this error message:

ERROR Error: Access is denied.
  "ERROR"
    [object Error]{description: "Access is d...", message: "Access is d...", name: "Error", number: -2147024891, stack: "Error: Acce..."}
    [functions]
    __proto__[object Error] {...}
    description"Access is denied. ...
    message"Access is denied. ...
    name"Error"
    number-2147024891
    stack"Error: Access is denied. ...

What can I do to resolve this in IE browsers?

ghostagent151
  • 1,218
  • 2
  • 16
  • 33

1 Answers1

2

IE doesn't support URL.createObjectURL() which you use in your methods for getting PDFs. IE has its own API for creating and downloading files, which is called msSaveBlob or msSaveOrOpenBlob.

The difference between the msSaveBlob and msSaveOrOpenBlob methods is that the former only provides a Save button to the user whereas the latter provides both a Save and an Open button. You could use them like this in IE:

window.navigator.msSaveOrOpenBlob(blobData, fileName);  

For more information, you could refer to this article in Microsoft and this thread.

---------------------------------------------------Edit-------------------------------------------------------

To make it cross browser, the code is like below:

if(window.navigator.msSaveOrOpenBlob) {
    //IE11 & Edge
    window.navigator.msSaveOrOpenBlob(blobData, fileName); 
}
else{
   //Other browsers
    window.URL.createObjectURL(blobData);
    ...
}

You could also refer to this simple sample I made: https://stackblitz.com/edit/angular-coueov

Yu Zhou
  • 11,532
  • 1
  • 8
  • 22
  • I've tried the suggestion you've put forth, however, I am getting this **error:** `core.js:15724 ERROR TypeError: window.navigator.msSaveOrOpenBlob is not a function` **I've replaced this line in my code:** `downloadLink.href = window.URL.createObjectURL(new Blob(binaryData, { type: dataType }));` **With this line:** `downloadLink.href = window.navigator.msSaveOrOpenBlob(new Blob(binaryData, { type: dataType }));` – ghostagent151 Oct 01 '19 at 16:50
  • Please don't just replace it as the `msSaveOrOpenBlob` is not supported in other browsers except IE 11 and Edge. If you use it in other browsers, it can show the error "not a function". You should check the condition if IE or other browsers. I've updated my answer. – Yu Zhou Oct 04 '19 at 07:40