chrome PDF viewer can't download file

…衆ロ難τιáo~ 提交于 2019-12-05 03:02:57

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.

Chrome's built in PDF viewer will download the pdf file through the PDF's origin URL. So if the PDF is generated at server runtime and if it's not stored in the sever, the download could fail.

see link here: https://productforums.google.com/forum/#!topic/chrome/YxyVToLN8ho

Just as an additional comment:

We had the same problem on a project, on Chrome only.

Authenticated GET request would fetch the PDF as an attachment from API, and we would forward it via window.createObjectURL(blob) to the browser viewer.

The Network Error was due us invoking window.revokeObjectURL(url); after opening the PDF. When we removed that line, the blob wasn't garbage collected immediately after opening.

fetch(request)
   .then(async response => {

       if (!response.ok) {
         return reject(response.statusText);
       }

       const blob = await response.blob();
       const url = await window.URL.createObjectURL(blob);

       window.open(url, '_blank');
       URL.revokeObjectURL(url); // This line was causing the problem
       resolve();
   })
   .catch(reject)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!