chrome PDF viewer can't download file

David LIu picture David LIu · May 26, 2017 · Viewed 7.8k times · Source

Here is my situation, I got a server running a PDF generator, when I make a request with some params, it will give me back a PDF file, the PDF is not stored in the server it's generated during the runtime.

Everything goes fine, I can get the PDF open in chrome's PDF viewer, but if want to download the file, an error occurred, like the image shows. enter image description here

Because Chrome go to the origin URL to request the file, but the file is not a static resource on the server.

I don't know if anybody has run into this problem?

Answer

flob picture flob · Jun 27, 2017

Whenever you leave the website you used to create the object URL (window.URL.createObjectURL(...)) that very object will get garbage collected. So you need to keep a reference to that object somehow.

This works for us in Chrome, Firefox, Safari, iOS Safari & Android to first display the PDF in capable browsers in a new tab and allow a download afterwards (in IE it just starts the download):

function openPdfInNewTab(url,
                         postData,
                         description = 'Document',
                         filename = description + '.pdf') {
  if (!window.navigator.msSaveOrOpenBlob) {
    var tabWindow = window.open('', '_blank');
    var a = tabWindow.document.createElement('a');
    a.textContent = 'Loading ' + description + '..';
    tabWindow.document.body.appendChild(a);
    tabWindow.document.body.style.cursor = 'wait';
  } else {
    spinnerService.show('html5spinner');
  }

  $http.post(url, postData, {responseType: 'arraybuffer'})
    .then(function showDocument(response) {
      var file = new Blob([response.data], {type: 'application/pdf'});
      if (window.navigator.msSaveOrOpenBlob) {
        spinnerService.hide('html5spinner');
        window.navigator.msSaveOrOpenBlob(file, filename);
      } else {
        tabWindow.document.body.style.cursor = 'auto';
        var url = a.href = window.URL.createObjectURL(file);
        a.click();
        a.download = filename;
      }
      $timeout(function revokeUrl() {
        window.URL.revokeObjectURL(url);
      }, 3600000);
    }, handleDownloadError);
}

We have been opening PDFs in a new browser-tab and had similar issues.

For us it started working again when we use window.URL.createObjectURL instead of tabWindow.URL.createObject which displayed the PDF but didn't allow the download.