Pdf.js: Erreur: autorisation refusée pour accéder à la propriété "impression"

Créé le 23 nov. 2018  ·  39Commentaires  ·  Source: mozilla/pdf.js

Configuration:

  • Navigateur Web et sa version: toutes les versions de Firefox depuis que PDF.js a été inclus (5+ ans)
  • Système d'exploitation et sa version: tous
  • Version PDF.js: tout
  • Est une extension de navigateur: n / a

Étapes pour reproduire le problème:

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

Quel est le comportement attendu?
Que le PDF peut s'imprimer comme dans tout autre navigateur que Firefox

Qu'est ce qui ne s'est pas bien passé?
Error: Permission denied to access property 'print'

Veuillez corriger cela car la solution d'impression universelle de PDF dans le navigateur est interrompue depuis 5 ans dans Firefox depuis que pdf.js a été inclus dans Firefox.

La communauté des développeurs Web a des centaines de mauvaises solutions à cela, à cause d'un seul projet, pdf.js.

4-printing

Commentaire le plus utile

@dotnetCarpenter la cerise sur le gâteau est que, il y a plus d'un an, l'un des développeurs s'est plaint que tous les commentaires +1 rendent plus difficile la

Tous les 39 commentaires

Similaire à https://github.com/mozilla/pdf.js/issues/5397 , mais peu importe si vous utilisez un iframe ou non.

Même problème si vous utilisez <object>

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

Étapes pour reproduire le problème:

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

Pourquoi ouvrir un problème de duplication ici, alors que cela est clairement déjà suivi dans Bugzilla !?
D'autant qu'il ne s'agit même pas d'un bogue dans la bibliothèque (générale) PDF.js elle-même, mais plutôt d'une limitation dans le navigateur Firefox (comme indiqué dans le bogue lié, et un correctif ne se produirait donc pas dans ce référentiel de toute façon).

@Snuffleupagus Parce que le bogue de Firefox a été signalé il y a 5 ans et que la cause première est pdf.js et non Firefox. Aucun développeur Firefox n'a touché à cela et j'ai rencontré ce problème plusieurs fois et il ne peut être résolu qu'en changeant pdf.js et non Firefox.

Pour clarifier, le fonctionnement de pdf.js est que l'impression normale (15+ ans) d'un document, print() , dans ce cas un PDF, génère une erreur lorsque

Je me trompe peut-être en disant que l'erreur est vraiment la façon dont pdf.js est intégré à Firefox. Mais je suppose que pdf.js pourrait plus facilement écouter print() et utiliser sa logique interne pour imprimer le document 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');   
};

Devrait fonctionner depuis Firefox 6

window.matchMedia('print') ne fonctionnera probablement pas car le bogue https://bugzilla.mozilla.org/show_bug.cgi?id=774398 n'est pas marqué comme corrigé ou résolu.

Il s'agit d'un doublon de # 5397 - la cause première du problème est que pdf.js est incorporé dans un document avec un principal de sécurité " resource: //pdf.js ". Il est différent du principal d'intégration, de sorte que la stratégie de même origine bloque l'accès à l'impression et à d'autres propriétés. Peu importe qu'il soit intégré dans une iframe ou un objet.

@Snuffleupagus fait-il partie du dossier Web du bundle pdf.js intégré à Firefox?
La seule logique d'impression que j'ai trouvée est dans https://github.com/mozilla/pdf.js/blob/master/web/firefox_print_service.js

Le principal problème avec # 5397 est qu'il s'agit à moitié d'imprimer lors de l'utilisation de pdf.js et à moitié de savoir comment imprimer un document dans Firefox lorsque pdf.js rend le document, comme dans ce ticket. @automatedbugreportingfacility vous avez raison, mais j'ai senti que cela nécessitait un nouveau problème puisque le # 5397 embrouille les eaux.

La modification de l'URI devrait se produire dans https://bugzilla.mozilla.org/show_bug.cgi?id=911444#c53 mais au lieu d'un correctif dans Firefox (cela n'a pas eu lieu depuis 5 ans), une solution serait d'écouter pour l'événement beforeprint et lancez l'impression via pdf.js. Si le beforeprint est bloqué par Firefox, en raison d'une politique de sécurité de même origine, cela ne peut se produire que dans Firefox.
Peut-être que l'un de vous peut clarifier la question?

une solution serait d'écouter l'événement beforeprint et de commencer l'impression via pdf.js.

Pouvez-vous clarifier? Pour que l'événement beforeprint soit envoyé à un document pdf.js incorporé, vous devez appeler print() dans le contexte d'une fenêtre parent. Le navigateur imprimera alors le contenu de la fenêtre parent. Vous ne pouvez pas "démarrer l'impression" dans le gestionnaire d'événements, car il avait déjà commencé à imprimer le document parent.

Une solution de contournement potentielle du côté pdf.js serait d'implémenter un gestionnaire onmessage pour permettre l'impression via pdfWindow.postMessage("print"); , mais je ne suis pas sûr que ce soit une solution souhaitée.

Une solution de contournement potentielle du côté pdf.js serait d'implémenter un gestionnaire onmessage pour permettre l'impression via pdfWindow.postMessage ("print") ;, mais je ne suis pas sûr que ce soit une solution souhaitée.

@automatedbugreportingfacility uf, non ce n'est pas du tout souhaitable. La solution parfaite serait d'avoir la parité de l'API DOM avec tous les autres navigateurs, où vous pouvez utiliser .print() sur le conteneur de document PDF.

Je n'ai pas créé ce problème parce que j'utilise pdf.js mais parce que Firefox utilise pdf.js et print() n'a pas fonctionné depuis que pdf.js est devenu la norme pour le rendu des PDF dans Firefox.

Je serai heureux si cela est corrigé dans Firefox et non dans pdf.js ou l'inverse - de toute façon, je serai heureux 😃

[...] alors cela ne peut arriver que dans Firefox.
Peut-être que l'un de vous peut clarifier la question?

Je déclare déjà dans https://github.com/mozilla/pdf.js/issues/10290#issuecomment -441132851 que ce n'est pas pertinent pour ce référentiel, et https://github.com/mozilla/pdf.js/issues/ 10290 # issuecomment -441202543 explique (en détail) pourquoi . Encore une fois, veuillez noter qu'il n'est pas nécessaire / souhaitable d'avoir des problèmes en double ouverts.

Afin de toucher même .print sans qu'une erreur de sécurité ne soit générée, un correctif est nécessaire pour la situation resource://pdf.js j'ai décrite ci-dessus, et cela serait fait dans Firefox. Nous pouvons fermer ce problème car il n'y a pas de travail pdf.js à faire ici, et le bogue en amont est reflété dans # 5397.

@Snuffleupagus et @automatedbugreportingfacility juste pour être sûr que je comprends ce que vous dites.

Il n'y a aucun moyen de créer une politique de sécurité de contournement de Firefox dans pdf.js, lorsque print() est appelé.

Ce qui précède est-il correct?

Oui, vous ne pouvez pas percer un trou dans les mécanismes de sécurité du navigateur. Intégrer pdf.js dans un document semi-privilégié était une grosse erreur au départ, mais il n'y a pas de retour en arrière, et Mozilla préfère tristement dépenser de l'argent pour des choses éphémères comme "Project Mortar". Mais je m'éloigne du sujet.

L'expérience Mortar est terminée. Mozilla ne considère pas que le cas d'utilisation PDF justifie la charge d'implémentation et de maintenance de PDFium et d'une implémentation d'API Pepper dans Gecko.

Au moins, Motar est abandonné .

Ce problème pourrait certainement être clos mais avant moi (vous), puisque j'ai 2 experts pdf.js ici, j'ai deux questions qui pourraient éventuellement aider https://bugzilla.mozilla.org/show_bug.cgi?id=911444 le long dans la bonne direction.

  1. Comment intégrer pdf.js dans Firefox, sinon en tant que document spécial (_resource: // protocol_)?
  2. Quelle est la mise en page papier lorsque Firefox imprime des pdf.js, des barres d'outils, etc.?

Intégrer pdf.js dans un document semi-privilégié était une grosse erreur au départ, mais il n'y a pas de retour en arrière

@automatedbugreportingfacility Pourquoi cette décision est-elle irréversible?

Ne pourriez-vous pas simplement créer un nouveau document vierge avec pdf.js et la même origine que la fenêtre parente et alimenter le fichier PDF en pdf.js?

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

Points bonus, si pdf.js écoute beforeprint , annulez l'événement et imprimez le <canvas> (document PDF) et ne laissez pas FIrefox imprimer l'interface utilisateur pdf.js.

J'imagine que si pdf.js était intégré en tant que document ordinaire, vous seriez en mesure d'écouter la fenêtre parente.

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

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

Ou remplacez pdf.js par:

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

À la réflexion, cela signifierait que pdf.js avalerait les impressions du parent, ce qui n'est pas ce que nous voulons.

En fait, pdf.js fait déjà la bonne chose. Nous avons juste besoin de Firefox pour envoyer print() sur le document qui intègre pdf.js.

Extrait de _pdf_print_service.js_ (trouvé sur 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 et @jtraulle Veuillez voter sur https://bugzilla.mozilla.org/show_bug.cgi?id=911444 pour le mettre sur le radar des développeurs Firefox.

Merci @dotnetCarpenter , j'ai voté sur Bugzilla 🐞

Eu le même problème en utilisant Firefox. Résolu, y compris le pdf dans un iframe comme celui-ci (la clé est la façon dont le pdf est lié):

`$ (". classe_div "). html ('