chrome PDF 查看器无法下载文件

chrome PDF viewer can't download file

这是我的情况,我有一个服务器 运行 一个 PDF 生成器,当我用一些参数发出请求时,它会返回一个 PDF 文件,PDF 没有存储在服务器中它是在 运行 时间内生成的。

一切顺利,我可以在 chrome 的 PDF 查看器中打开 PDF,但是如果要下载文件,出现错误,如图所示。

因为Chrome去原点URL请求文件,但是文件不是服务器上的静态资源

不知道有没有人运行遇到这个问题?

Chrome 的内置 PDF 查看器将通过 PDF 源 URL 下载 pdf 文件。因此,如果 PDF 在服务器运行时生成并且未存储在服务器中,则下载可能会失败。

请在此处查看 link:https://productforums.google.com/forum/#!topic/chrome/YxyVToLN8ho

每当您离开您用来创建对象URL (window.URL.createObjectURL(...)) 的网站时,该对象将被收集垃圾。所以你需要以某种方式保留对该对象的引用。

这在 Chrome、Firefox、Safari、iOS Safari 和 Android 中对我们有用,以便首先在支持的浏览器中 在新选项卡中显示 PDF 然后允许下载(在 IE 中它只是开始下载):

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);
}

我们一直在新的浏览器选项卡中打开 PDF,但遇到了类似的问题。

对我们来说,当我们使用 window.URL.createObjectURL 而不是显示 PDF 但不允许下载的 tabWindow.URL.createObject 时,它又开始工作了。

作为附加评论:

我们在一个项目上遇到了同样的问题,仅在 Chrome 上。

经过身份验证的 GET 请求将从 API 获取 PDF 作为附件,我们将通过 window.createObjectURL(blob) 将其转发给浏览器查看器。

Network Error 是由于我们在打开 PDF 后调用 window.revokeObjectURL(url);。当我们删除该行时,blob 不会在打开后立即被垃圾回收。

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)