Pdf.js: エラー:プロパティ 'print'へのアクセスが許可されていません

作成日 2018年11月23日  ·  39コメント  ·  ソース: mozilla/pdf.js

構成:

  • Webブラウザとそのバージョン:PDF.jsが含まれてからのFirefoxのすべてのバージョン(5年以上)
  • オペレーティングシステムとそのバージョン:すべて
  • PDF.jsバージョン:すべて
  • ブラウザ拡張機能です:該当なし

問題を再現する手順:

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

期待される動作は何ですか?
PDFがFirefox以外のすべてのブラウザと同じように印刷できること

何が悪かったのか?
Error: Permission denied to access property 'print'

pdf.jsがFirefoxに含まれて以来、ブラウザでのPDFのユニバーサル印刷ソリューションへの移行がFirefoxで5年間壊れているため、これを修正してください。

単一のプロジェクトpdf.jsがあるため、Web開発者コミュニティにはこれに対する何百もの悪い解決策があります。

4-printing

最も参考になるコメント

@dotnetCarpenterのアイシングは、1年以上前に、開発者の1人が、すべての+1コメントによって技術的な議論が

全てのコメント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の開発者はこれに触れていません。私はこの問題に何度も遭遇しましたが、Firefoxではなく

明確にするために、 pdf.jsが機能する方法は、ドキュメント、 print() 、この場合はPDFを印刷する通常の(15年以上)がpdf.jsを使用するとエラーをスローすることです。過去5年間のFirefoxでのPDFのデフォルト表示方法。

エラーが実際にpdf.jsがFirefoxに埋め込まれている方法であると私は間違っているかもしれません。 しかし、pdf.jsはprint()をより簡単にリッスンし、その内部ロジックを使用して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');   
};

Firefox6以降で動作するはずです

バグhttps://bugzilla.mozilla.org/show_bug.cgi?id=774398が修正済みまたは解決済みとしてマークされていないため、 window.matchMedia('print')はおそらく機能しません。

これは#5397の複製です。問題の根本的な原因は、pdf.jsが「 resource://pdf.js 」セキュリティプリンシパルを持つドキュメントに埋め込まれていることです。 埋め込みプリンシパルとは異なるため、同一生成元ポリシーは印刷やその他のプロパティへのアクセスをブロックします。 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でのみ発生する可能性があります。
おそらくあなたの一人が問題を明確にすることができますか?

回避策は、beforeprintイベントをリッスンし、pdf.jsを介して印刷を開始することです。

明確にできますか? beforeprintイベントを埋め込みpdf.jsドキュメントに送信するには、親ウィンドウのコンテキストでprint()を呼び出す必要があります。 その後、ブラウザは親ウィンドウのコンテンツを印刷します。 親ドキュメントの印刷がすでに開始されているため、イベントハンドラーで「印刷を開始」することはできません。

pdf.js側の電位回避策が実装するだろうonmessageを通じて印刷を許可するようにハンドラをpdfWindow.postMessage("print");が、それは必要なソリューションだ場合、私はよく分かりません。

pdf.js側の潜在的な回避策は、pdfWindow.postMessage( "print");を介した印刷を可能にするonmessageハンドラーを実装することですが、それが望ましい解決策であるかどうかはわかりません。

@automatedbugreportingfacility uf 、いいえ、それはまったく望ましくありません。 完璧な解決策は、他のすべてのブラウザとDOM APIを同等にすることです。この場合、PDFドキュメントコンテナで.print()を使用できます。

pdf.jsを使用しているため、この問題は発生しませんでしたが、Firefoxはpdf.jsを使用し、pdf.jsがFirefoxでPDFをレンダリングするための標準になったため、 print()は機能しませんでした。

これがpdf.jsではなくFirefoxで修正されれば、私は幸せになります-どちらにしても私は幸せになります😃

[...]その後、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は悲しいことに「ProjectMortar」のような一時的なものにお金を使うことを好みます。 しかし、私は余談です。

モルタル実験は終了しました。 Mozillaは、PDFのユースケースがGeckoでのPDFiumとPepperAPIの実装の実装と保守の負担を正当化するとは考えていません。

少なくともMotarは廃止されました

この問題は確実に解決される可能性がありますが、私(あなた)が解決する前に、ここに2人のpdf.jsエキスパートがいるので、 https: //bugzilla.mozilla.org/show_bug.cgi?id = 911444に役立つ可能性のある2つの質問があります

  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.jsUIを印刷させないようにします。

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はすでに正しいことをしています。 pdf.jsを埋め込んだドキュメントにprint()をディスパッチするには、Firefoxが必要です。

_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に感謝し

Firefoxを使用して同じ問題が発生しました。 PDFを含めて次のように解決しました(重要なのはPDFのリンク方法です)。

`$("。div_class ")。html( '