Pdf.js: Ошибка: отказано в доступе к свойству print

Созданный на 23 нояб. 2018  ·  39Комментарии  ·  Источник: mozilla/pdf.js

Конфигурация:

  • Веб-браузер и его версия: все версии Firefox с момента включения PDF.js (5+ лет)
  • Операционная система и ее версия: все
  • Версия PDF.js: все
  • Расширение для браузера: н / д

Шаги по воспроизведению проблемы:

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

Какое ожидаемое поведение?
PDF-файл можно печатать как в любом другом браузере, кроме Firefox.

Что пошло не так?
Error: Permission denied to access property 'print'

Пожалуйста, исправьте это, поскольку переход на универсальное решение для печати PDF-файлов в браузере не работает в Firefox в течение 5 лет с тех пор, как pdf.js был включен в Firefox.

Сообщество веб-разработчиков предлагает сотни плохих решений для этого из-за одного проекта, pdf.js.

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+ лет) печать документа print() , в данном случае 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');   
};

Должен работать с Firefox 6

window.matchMedia('print') , вероятно, не будет работать, поскольку ошибка https://bugzilla.mozilla.org/show_bug.cgi?id=774398 не помечена как исправленная или устраненная.

Это дубликат # 5397 - основная причина проблемы в том, что pdf.js встроен в документ с участником безопасности " resource: //pdf.js ". Он отличается от принципала внедрения, поэтому политика одного и того же происхождения блокирует доступ к печати и другим свойствам. Не имеет значения, встроен ли он в iframe или в объект.

@Snuffleupagus - это часть веб-папки из пакета pdf.js, встроенного в Firefox?
Единственная логика печати, которую я нашел, находится в https://github.com/mozilla/pdf.js/blob/master/web/firefox_print_service.js

Основная проблема с # 5397 заключается в том, что наполовину речь идет о печати при использовании pdf.js, а наполовину о том, как распечатать документ в Firefox, когда pdf.js отображает документ, как в этом билете. @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 - реализовать обработчик onmessage, позволяющий печатать через pdfWindow.postMessage ("print");, но я не уверен, что это желаемое решение.

@automatedbugreportingfacility uf, нет, это совсем не желательно. Идеальным решением было бы иметь паритет DOM API со всеми другими браузерами, где вы можете использовать .print() в контейнере PDF-документа.

Я создавал эту проблему не потому, что использую pdf.js, а потому, что Firefox использует pdf.js, а print() не работает с тех пор, как pdf.js стал стандартом для рендеринга PDF-файлов в Firefox.

Я буду рад, если это исправят в 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, чтобы быть уверенным, что я понимаю, что вы говорите.

Невозможно создать временную политику безопасности Firefox в pdf.js, когда вызывается print() .

Верно ли вышесказанное?

Да, вы не можете пробить брешь в механизмах безопасности браузера. Встраивание pdf.js в полу-привилегированный документ изначально было большой ошибкой, но пути назад нет, и Mozilla, к сожалению, предпочитает тратить деньги на эфемерные вещи, такие как «Project Mortar». Но я отвлекся.

Эксперимент с минометом завершен. Mozilla не считает, что вариант использования PDF оправдывает бремя реализации и поддержки PDFium и Pepper API в Gecko.

Ну хоть Мотар снят с производства .

Эту проблему определенно можно было бы закрыть, но прежде чем я (вы) это сделаю, поскольку у меня здесь 2 эксперта по pdf.js, у меня есть два вопроса, которые, возможно, могут помочь https://bugzilla.mozilla.org/show_bug.cgi?id=911444 вместе в правильном направлении.

  1. Как встраивать pdf.js в Firefox, если не как специальный документ (_resource: // protocol_)?
  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.

Я полагаю, если бы 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 для отправки print() в документ, в который встроен pdf.js.

Выдержка из _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 ('