Pdf.js: 错误:拒绝访问属性“打印”的权限

创建于 2018-11-23  ·  39评论  ·  资料来源: mozilla/pdf.js

组态:

  • Web浏览器及其版本:自包含PDF.js以来的所有Firefox版本(超过5年)
  • 操作系统及其版本:全部
  • PDF.js版本:全部
  • 是浏览器扩展程序:n / a

重现此问题的步骤:

  1. https://bugzilla.mozilla.org/show_bug.cgi?id=911444

预期的行为是什么?
PDF可以像Firefox之外的其他所有浏览器一样打印

什么地方出了错?
Error: Permission denied to access property 'print'

请解决此问题,因为自Firefox包含pdf.js以来,Firefox中浏览器PDF的通用打印解决方案已被中断5年。

由于单个项目pdf.js ,Web开发人员社区对此有数百种不良解决方案。

4-printing

最有用的评论

@dotnetCarpenter锦上添花的是,一年多以前,一位开发人员抱怨说,所有+1注释都使得查看技术性讨论更加困难,因此也难以解决该错误。 好像这就是为什么它开放超过6年并不断增加的原因。 没有投票系统,这些评论现在是引起人们注意的唯一方法,因此,我认为别无选择。

所有39条评论

https://github.com/mozilla/pdf.js/issues/5397相似,但是是否使用iframe没有关系。

如果使用<object>则会出现相同的问题

<object type="application/pdf"
    data="/media/examples/In-CC0.pdf"
    width="250"
    height="200">
</object>

重现此问题的步骤:

1. https://bugzilla.mozilla.org/show_bug.cgi?id=911444#c53

如果在Bugzilla中已经明确跟踪了此问题,为什么还要在此处打开重复的问题?
特别是因为这甚至不是(通用)PDF.js库本身中的错误,而是Firefox浏览器中的一个限制(如链接的错误中所述,因此该存储库中也不会发生任何修复)。

@Snuffleupagus因为Firefox错误是5年前报告的,其根本原因是pdf.js,而不是Firefox。 没有Firefox开发人员可以解决这个问题,我已经多次遇到这个问题,只能通过更改pdf.js而不是Firefox来解决。

澄清一下, pdf.js的工作方式是正常打印文档(15年以上),在使用pdf.js的情况下,在这种情况下为PDF, print()抛出错误。过去5年在Firefox中显示PDF的默认方式。

我可能是错的,因为错误实际上pdf.jsprint()并使用其内部逻辑来打印PDF文档。

window.onbeforeprint = function() {
    console.log('This will be called before the user prints.');
};
window.onafterprint = function() {
    console.log('This will be called after the user prints');   
};

自Firefox 6起应该可以使用

window.matchMedia('print')可能无法工作,因为错误https://bugzilla.mozilla.org/show_bug.cgi?id=774398未标记为已修复或已解决。

这是#5397的重复副本–问题的根本原因是pdf.js嵌入到具有“ resource://pdf.js ”安全主体的文档中。 它与嵌入主体不同,因此同源策略会阻止对print和其他属性的访问。 嵌入到iframe还是对象中都没关系。

@Snuffleupagus是Firefox中嵌入的pdf.js软件包的Web文件夹部分吗?
我发现的唯一打印逻辑是在https://github.com/mozilla/pdf.js/blob/master/web/firefox_print_service.js

#5397的主要问题是,一半是关于使用pdf.js时的打印,另一半是关于pdf.js呈现文档时如何在Firefox中打印文档的,就像这张票证一样。 @automatedbugreportingfacility你是正确的,但是我觉得这需要一个新的问题,因为#5397令人困惑。

更改URI应该在https://bugzilla.mozilla.org/show_bug.cgi?id=911444#c53中进行,但是代替Firefox中的修复(5年内不会发生),一种解决方法是监听参加beforeprint事件,并开始通过pdf.js打印。 如果beforeprint由于相同的安全策略而被Firefox阻止,则只能在Firefox中发生。
也许你们其中一个可以澄清这个问题?

解决方法是监听preprint事件并通过pdf.js开始打印。

你能澄清一下吗? 为了将beforeprint事件发送到嵌入式pdf.js文档,您需要在父窗口的上下文中调用print() 。 然后,浏览器将打印父窗口的内容。 您无法在事件处理程序中“开始打印”,因为它已经开始打印父文档。

pdf.js方面可能的解决方法是实现onmessage处理程序,以允许通过pdfWindow.postMessage("print");打印,但是我不确定这是否是理想的解决方案。

pdf.js方面的一种可能的解决方法是实现onmessage处理程序以允许通过pdfWindow.postMessage(“ print”);进行打印,但是我不确定这是否是理想的解决方案。

@automatedbugreportingfacility uf,这根本不是不希望的。 完美的解决方案是与所有其他浏览器具有DOM API奇偶校验,您可以在其中使用.print()在PDF文档容器上。

我没有创建此问题,因为我使用的是pdf.js,但是由于Firefox使用的是pdf.js,并且自pdf.js成为在Firefox中呈现PDF的标准以来, print()一直没有用。

如果在Firefox中解决此问题,而不是在pdf.js中解决此问题,我会很高兴-要么我会很高兴😃

[...]那么它只能在Firefox中发生。
也许你们其中一个可以澄清这个问题?

我已经在https://github.com/mozilla/pdf.js/issues/10290#issuecomment -441132851中声明与存储库无关,以及https://github.com/mozilla/pdf.js/issues/ 10290#issuecomment -441202543概述了(为什么会这样)。 同样,请注意,没有必要/不希望重复出现问题。

为了甚至触摸.print而不会引发安全错误,需要针对我在上文中描述的resource://pdf.js情况进行修复,这将在Firefox中完成。 由于这里没有pdf.js的工作,并且我们在#5397中反映了上游错误,因此我们可以解决此问题。

@Snuffleupagus@automatedbugreportingfacility只是为了确保我理解您在说什么。

调用print()时,无法在pdf.js中创建变通方法Firefox安全策略。

以上正确吗?

是的,您无法在浏览器的安全性机制上打个洞。 首先,将pdf.js嵌入半特权文档中是一个大错误,但是没有回头路了,Mozilla遗憾地更喜欢花钱购买“ Project Mortar”这类临时性的东西。 但是我离题了。

砂浆实验已经结束。 Mozilla认为PDF用例不能证明在Gecko中实现和维护PDFium和Pepper API实现的负担。

那么至少Motar已停产

这个问题肯定可以解决,但是在我(您)这样做之前,由于我在这里拥有2位pdf.js专家,所以我有两个问题可能会帮助https://bugzilla.mozilla.org/show_bug.cgi?id=911444在正确的方向。

  1. 如果不是作为特殊文档(_resource:// protocol_),应如何将pdf.js嵌入Firefox?
  2. 当Firefox打印pdf.js,工具栏等时,纸张打印布局是什么?

首先将pdf.js嵌入半特权文档中是一个大错误,但没有回头路可走

@automatedbugreportingfacility为什么这个决定是不可逆的?

您难道不可以使用pdf.js创建一个新的空白文档,并且其原始来源与父窗口相同,然后将PDF文件提供给pdf.js吗?

<iframe id="pdf" src="some-same-origin.pdf"></iframe>
<script>
  document.getElementById('pdf').print()
</script>

奖励积分是,如果pdf.js收听beforeprint ,则取消该事件并打印<canvas> (PDF文档),而不让FIrefox打印pdf.js UI。

我想,如果将pdf.js作为常规文档嵌入,您将能够收听父窗口。

window.opener.addEventListener('beforeprint', event => {
  event.preventDefault()

  window.print() // pdf.js overrides the native print function already
})

或将pdf.js更改为:

let print = (window.opener || window).print;
window.print = function print() {
  if (activeService) {
    console.warn('Ignored window.print() because of a pending print job.');
    return;
  }
  ...

再三考虑,这意味着pdf.js会吞下父级的打印品,这不是我们想要的。

实际上pdf.js已经在做正确的事情。 我们只需要firefox在嵌入pdf.js的文档上调度print()

摘录自_pdf_print_service.js_(位于https://mozilla.github.io/pdf.js/web/viewer.html):

let print = window.print;
window.print = function print() {
  if (activeService) {
    console.warn('Ignored window.print() because of a pending print job.');
    return;
  }
  ensureOverlay().then(function() {
    if (activeService) {
      overlayManager.open('printServiceOverlay');
    }
  });

  try {
    dispatchEvent('beforeprint');
  } finally {
    if (!activeService) {
      console.error('Expected print service to be initialized.');
      ensureOverlay().then(function() {
        if (overlayManager.active === 'printServiceOverlay') {
          overlayManager.close('printServiceOverlay');
        }
      });
      return; // eslint-disable-line no-unsafe-finally
    }
    let activeServiceOnEntry = activeService;
    activeService.renderPages().then(function() {
      return activeServiceOnEntry.performPrint();
    }).catch(function() {
      // Ignore any error messages.
    }).then(function() {
      // aborts acts on the "active" print request, so we need to check
      // whether the print request (activeServiceOnEntry) is still active.
      // Without the check, an unrelated print request (created after aborting
      // this print request while the pages were being generated) would be
      // aborted.
      if (activeServiceOnEntry.active) {
        abort();
      }
    });
  }
};

function dispatchEvent(eventType) {
  let event = document.createEvent('CustomEvent');
  event.initCustomEvent(eventType, false, false, 'custom');
  window.dispatchEvent(event);
}

function abort() {
  if (activeService) {
    activeService.destroy();
    dispatchEvent('afterprint');
  }
}

@Ugoku@jtraulle请在https://bugzilla.mozilla.org/show_bug.cgi?id=911444上投票,以使其受到Firefox开发人员的关注。

感谢@dotnetCarpenter ,我对Bugzilla🐞进行了投票

使用Firefox遇到了相同的问题。 将包含pdf的文件解决成这样的iframe(关键是pdf的链接方式):

`$(“。div_class”)。html('