does_not_compute
does_not_compute

Reputation: 476

Sending PDF To Client as BLOB, But lacks browser support

I'm currently calling an external API in order to get a payslip sent to me (Sent in binary over to my node server as I have to use certificate authentication on the node side)

I've managed to figure out how to get my client to download this on chrome by sending it as a binary object, then using createObjectURL to load it, however this isn't working on any IE versions.

I've tried various solutions but can't seem to get the compatability i'm after, I was wondering if anyone would be able to give advice on what my options are for ensuring IE8 compatibility > on the client side when serving the PDF?

Server is currently sending the recieved PDF data like so

res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename=myPdf.pdf');
res.write(pay_pdf_data, 'binary');
res.end(); 

Current method on client which works fine on chrome but doesn't work in IE / Older browsers

function httpGetAsync(theUrl, data, callback) {
    var request = new XMLHttpRequest();
    request.open("POST", theUrl, true); 
    request.responseType = "blob";
    request.onload = function (e) {
        if (this.status === 200) {
            // `blob` response
            console.log(this.response);
            // create `objectURL` of `this.response` : `.pdf` as `Blob`
            var file = window.URL.createObjectURL(this.response);
            var a = document.createElement("a");
            a.href = file;
            a.download = this.response.name || "detailPDF";
            document.body.appendChild(a);
            a.click();
            // remove `a` following `Save As` dialog, 
            // `window` regains `focus`
            window.onfocus = function () {                     
              document.body.removeChild(a)
            }
        };
    };
    request.setRequestHeader("Content-Type", "application/json");
    request.send(data);
}

Thanks!

Upvotes: 0

Views: 2488

Answers (1)

charmeleon
charmeleon

Reputation: 2755

IE does not support the download attribute on anchor tags: http://caniuse.com/#search=download.

For IE10/IE11, you can use window.navigator.msSaveOrOpenBlob, but for IE8/IE9 you need to add a hack that involves an invisible iframe on your page:

<iframe name="seekritDownload" style="display:none"></iframe>

As an alternative, you can try this:

function httpGetAsync(theUrl, data, callback) {
  var request = new XMLHttpRequest();
  request.open("POST", theUrl, true); 
  // IE10/IE11 and other modern browsers
  if ('responseType' in request) {
    request.responseType = "blob";
    request.onload = function (e) {
      if (this.status === 200) {
        // `blob` response
        console.log(this.response);
        // IE10/IE11
        if ('msSaveOrOpenBlob' in window.navigator) {
          // Here I assume `this.response` is the blob
          window.navigator.msSaveOrOpenBlob(this.response, this.response.name || "detailPDF");
        }
        else {
          // create `objectURL` of `this.response` : `.pdf` as `Blob`
          var file = window.URL.createObjectURL(this.response);
          var a = document.createElement("a");
          a.href = file;
          a.download = this.response.name || "detailPDF";
          document.body.appendChild(a);
          a.click();
          // remove `a` following `Save As` dialog, 
          // `window` regains `focus`
          window.onfocus = function () {                     
            document.body.removeChild(a)
          }
        }
      }
    };
    request.setRequestHeader("Content-Type", "application/json");
    request.send(data);
  }
  else {
    // This should work for IE8/IE9
    window.open(theUrl, 'seekritDownload');
  }
}

For reference, see: https://msdn.microsoft.com/en-us/library/hh779016(v=vs.85).aspx

EDIT: Besides the missing download attribute, IE8 lacks XMLHttpRequest.responseType and the Blob object. I added a HUGE hack with an iframe that should work. If you prefer, you can create and append the iframe element with JavaScript instead

Upvotes: 1

Related Questions