【问题标题】:chrome PDF viewer can't download filechrome PDF 查看器无法下载文件
【发布时间】:2017-10-27 01:08:52
【问题描述】:

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

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

因为Chrome是去源地址请求文件的,但是文件不是服务器上的静态资源。

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

【问题讨论】:

  • 我们遇到了同样的问题...目前还没有解决方案。
  • 您是否尝试过这里建议的解决方案:stackoverflow.com/a/21732039/510711
  • @flob 我已经在 Google chrome 的群组中发布了这个,据说通过 pdf 的原始 URL 下载 PDF 是 Chrome 内置 PDF 查看器的默认行为。现在我们的解决方案是使用“PDF.js”作为我们服务器中内置的默认 PDF 查看器。有关更多信息,您可以查看“PDF.js”github 页面。
  • 我们找到了解决方案,在发布答案时我意识到这是由于用于 createObjectURL 的窗口对象在显示的 PDF 替换网站后立即被垃圾收集。

标签: google-chrome pdf pdf-viewer


【解决方案1】:

每当您离开您用来创建对象 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 时,它又开始工作了。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      作为附加评论:

      我们在一个项目中遇到了同样的问题,仅在 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)
      

      【讨论】:

      • 非常感谢URL.revokeObjectURL(url); // This line was causing the problem 我花了 10 多个小时来调试 Chrome 特有的问题,因为你,我把它缩小到这一行。
      • 解决了我的问题!
      猜你喜欢
      • 2019-08-04
      • 2022-09-27
      • 2018-07-05
      • 1970-01-01
      • 2012-09-15
      • 2018-05-22
      • 2018-05-21
      • 2017-01-23
      • 2018-11-17
      相关资源
      最近更新 更多