Pdf.js: Error: permiso denegado para acceder a la propiedad 'imprimir'

Creado en 23 nov. 2018  ·  39Comentarios  ·  Fuente: mozilla/pdf.js

Configuración:

  • Navegador web y su versión: todas las versiones de Firefox desde que se incluyó PDF.js (más de 5 años)
  • Sistema operativo y su versión: todos
  • Versión PDF.js: todas
  • Es una extensión de navegador: n / a

Pasos para reproducir el problema:

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

¿Cuál es el comportamiento esperado?
Que el PDF se puede imprimir como en cualquier otro navegador que no sea Firefox

¿Qué salió mal?
Error: Permission denied to access property 'print'

Solucione este problema, ya que la solución de impresión universal de PDF en el navegador se ha roto durante 5 años en Firefox desde que se incluyó pdf.js en Firefox.

La comunidad de desarrolladores web tiene cientos de malas soluciones para esto, debido a un solo proyecto, pdf.js.

4-printing

Comentario más útil

@dotnetCarpenter la guinda del pastel es que, hace más de un año, uno de los desarrolladores se quejó de que todos los comentarios +1 hacen que sea más difícil ver la discusión técnica y, por lo tanto, más difícil resolver el error. Como si fuera por eso que ha estado abierto durante más de 6 años y contando. Sin el sistema de votación, estos comentarios son ahora la ÚNICA forma de llamar la atención sobre un problema, por lo que no veo otra alternativa.

Todos 39 comentarios

Similar a https://github.com/mozilla/pdf.js/issues/5397 , pero no importa si usa un iframe o no.

Mismo problema si usa <object>

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

Pasos para reproducir el problema:

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

¿Por qué abrir un problema duplicado aquí, cuando esto claramente ya está rastreado en Bugzilla?
Especialmente porque esto ni siquiera es un error en la biblioteca (general) PDF.js en sí, sino más bien una limitación en el navegador Firefox (como se describe en el error vinculado, y por lo tanto, una solución no sucedería en este repositorio de todos modos).

@Snuffleupagus Porque el error de Firefox se informó hace 5 años y la causa principal es pdf.js y no Firefox. Ningún desarrollador de Firefox ha tocado esto y me he encontrado con este problema varias veces y solo se puede resolver cambiando pdf.js, no Firefox.

Para aclarar, la forma en que funciona pdf.js es que lo normal (más de 15 años) de imprimir un documento, print() , en este caso un PDF, arroja un error cuando se usa pdf.js , que es el forma predeterminada de mostrar un PDF en Firefox durante los últimos 5 años.

Podría estar equivocado en que el error es realmente cómo se incrusta pdf.js en Firefox. Pero supongo que pdf.js podría escuchar más fácilmente print() y usar su lógica interna para imprimir el documento 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');   
};

Debería funcionar desde Firefox 6

window.matchMedia('print') probablemente no funcionará ya que el error https://bugzilla.mozilla.org/show_bug.cgi?id=774398 no está marcado como fijo o resuelto.

Este es un duplicado de # 5397 - la causa raíz del problema es que pdf.js está incrustado en un documento con una entidad de seguridad "

@Snuffleupagus ¿ es la carpeta web parte del paquete pdf.js que está incrustado en Firefox?
La única lógica de impresión que he encontrado está en https://github.com/mozilla/pdf.js/blob/master/web/firefox_print_service.js

El problema principal con # 5397 es que se trata de imprimir cuando se usa pdf.js y la mitad de cómo imprimir un documento en Firefox cuando pdf.js está procesando el documento, como en este ticket. @automatedbugreportingfacility tiene razón, pero sentí que esto requiere un nuevo problema ya que el número 5397 está enturbiando las aguas.

El cambio de URI debería ocurrir en https://bugzilla.mozilla.org/show_bug.cgi?id=911444#c53 pero en lugar de una solución en Firefox (no ha sucedido en 5 años), una solución sería escuchar para el evento beforeprint y comience a imprimir a través de pdf.js. Si Firefox bloquea el beforeprint debido a una política de seguridad del mismo origen, solo puede suceder en Firefox.
¿Quizás alguno de ustedes pueda aclarar el asunto?

una solución alternativa sería escuchar el evento beforeprint y comenzar a imprimir a través de pdf.js.

¿Puedes aclarar? Para que el evento beforeprint se envíe a un documento pdf.js incrustado, debe invocar print() en el contexto de una ventana principal. Luego, el navegador imprimirá el contenido de la ventana principal. No puede "comenzar a imprimir" en el controlador de eventos, porque ya había comenzado a imprimir el documento principal.

Una posible solución alternativa en el lado de pdf.js sería implementar un controlador onmessage para permitir la impresión a través de pdfWindow.postMessage("print"); , pero no estoy seguro de si es la solución deseada.

Una posible solución alternativa en el lado de pdf.js sería implementar un controlador onmessage para permitir la impresión a través de pdfWindow.postMessage ("print") ;, pero no estoy seguro de si es la solución deseada.

@automatedbugreportingfacility uf, no, eso no es deseable en absoluto. La solución perfecta sería tener la paridad DOM API con todos los demás navegadores, donde puede usar .print() en el contenedor de documentos PDF.

No creé este problema porque uso pdf.js sino porque Firefox usa pdf.js y print() no ha funcionado desde que pdf.js se convirtió en el estándar para renderizar PDF en Firefox.

Estaré feliz si esto se soluciona en Firefox y no en pdf.js o al revés, de cualquier manera estaré feliz 😃

[...] entonces solo puede suceder en Firefox.
¿Quizás alguno de ustedes pueda aclarar el asunto?

Ya indico en https://github.com/mozilla/pdf.js/issues/10290#issuecomment -441132851 que no es relevante para este repositorio, y https://github.com/mozilla/pdf.js/issues/ 10290 # issuecomment -441202543 describe (con cierto detalle) por qué es así. Nuevamente, tenga en cuenta que no es necesario / deseable tener abiertos problemas duplicados.

Para incluso tocar .print sin que se produzca un error de seguridad, se necesita una solución para la situación resource://pdf.js que describí anteriormente, y esto se haría en Firefox. Podemos cerrar este problema ya que no hay trabajo de pdf.js aquí, y el error de flujo ascendente se refleja en # 5397.

@Snuffleupagus y @automatedbugreportingfacility solo para asegurarme de que entiendo lo que está diciendo.

No hay forma de crear una política de seguridad alternativa para Firefox en pdf.js, cuando se llama a print() .

¿Es correcto lo anterior?

Sí, no puede hacer un agujero en los mecanismos de seguridad del navegador. Incrustar pdf.js en un documento semi-privilegiado fue un gran error en primer lugar, pero no hay vuelta atrás, y Mozilla lamentablemente prefiere gastar dinero en cosas efímeras como "Proyecto Mortero". Pero yo divago.

El experimento del Mortero ha concluido. Mozilla no considera que el caso de uso de PDF justifique la carga de implementar y mantener PDFium y una implementación de API de Pepper en Gecko.

Bueno, al menos Motar está descontinuado .

Este problema definitivamente podría cerrarse, pero antes de que yo (usted) lo haga, ya que tengo 2 expertos en pdf.js aquí, tengo dos preguntas que posiblemente podrían ayudar a https://bugzilla.mozilla.org/show_bug.cgi?id=911444 en la dirección correcta.

  1. ¿Cómo debería incrustarse pdf.js en Firefox, si no como un documento especial (_resource: // protocol_)?
  2. ¿Cuál es el diseño de impresión en papel cuando Firefox imprime pdf.js, barras de herramientas, etc.?

Incrustar pdf.js en un documento semi-privilegiado fue un gran error en primer lugar, pero no hay vuelta atrás

@automatedbugreportingfacility ¿

¿No podría simplemente crear un nuevo documento en blanco con pdf.js y el mismo origen que la ventana principal y alimentar el archivo PDF a pdf.js?

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

Puntos de bonificación, si pdf.js escucha beforeprint , cancele el evento e imprima el <canvas> (documento PDF) y no permita que FIrefox imprima la interfaz de usuario de pdf.js.

Me imagino que si pdf.js estuviera incrustado como un documento normal, podría escuchar la ventana principal.

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

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

O cambie pdf.js a:

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

Pensándolo bien, esto significaría que pdf.js se tragaría las impresiones del padre, que no es lo que queremos.

En realidad, pdf.js ya está haciendo lo correcto. Solo necesitamos que Firefox envíe print() en el documento que incrusta pdf.js.

Extracto de _pdf_print_service.js_ (que se encuentra en 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 y @jtraulle Vota en https://bugzilla.mozilla.org/show_bug.cgi?id=911444 para ponerlo en el radar de los desarrolladores de Firefox.

Gracias @dotnetCarpenter , he votado por Bugzilla 🐞

Tuve el mismo problema al usar Firefox. Lo resolvió incluyendo el pdf en un iframe como este (la clave es la forma en que está vinculado el pdf):

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