Search code examples
angularpdfangular5internet-explorer-11microsoft-edge

Render PDF in Edge and IE11 in an Embed


I thought I had a solution for this using an embed so that Adobe would render the PDF in the browsers when I did:

<embed src="./assets/pdf/example-1.pdf"
       width="100%"
       height="675px"
       style="border: 1px solid red"
       type="application/pdf">

But when I try to dynamically set the embed src using URL.createObjectURL(blob) and bind it to the embed in Angular it doesn't render:

<embed [src]="url"
       width="100%"
       height="675px"
       style="border: 1px solid red"
       type="application/pdf">

Is there more to rendering a PDF in an embed using a blob other then:

this.http(..., { responseType: 'blob', observe: 'response' })
  .subscribe((blob) => {

    url = URL.createObjectURL(blob);

    this.url = this.domSanitizer
      .bypassSecurityTrustResourceUrl(url);
  });

I know I can use PDF.js with Angular using a plugin, but I can't figure out how to use ViewerJS with it to get the controls for panning, zoom, etc. So I just want to display the PDF sent down in the response using Adobe in Edge and IE11. It can be in an iframe, but this only worked in Edge and not in IE11 with no displayed errors

For example, using this was suggested for cross browser compatibility when receiving a base64 of the PDF, but it only works for Edge not IE11.

  // Default to Chrome
  let url = `data:application/pdf;base64,${src}`;

  // Internet Explorer 11 and Edge workaround
  if (window.navigator && window.navigator.msSaveOrOpenBlob) {
    const byteCharacters = atob(src);
    const byteNumbers = new Array(byteCharacters.length);
    for (let i = 0; i < byteCharacters.length; i++) {
      byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    const blob = new Blob([byteArray], { type: 'application/pdf' });

    url = URL.createObjectURL(blob);

    if (this.url) {
      // Release URLs for performance and memory usage
      this.window.URL.revokeObjectURL(this.url);
    }
  }

  this.url = this.domSanitizer
    .bypassSecurityTrustResourceUrl(url);


<iframe id="result"
        [src]="url"
        style="width: 100%; height: 95vh; border: 1px solid red;"
        sandbox></iframe>

Solution

  • This all works for IE11 if you remove the sandbox attribute from the iframe. Sooo by removing security restrictions provided by sandbox IE11 works even though caniuse.com indicates it is compliant with IE11.