Почему создание PDF-файлов Puppeteer не работает в Windows?

У меня есть приложение NodeJs, которое пытается создать PDF-файл из HTML. Он работает на Mac, но не на Windows (время истекло). Вот код.

const puppeteer = require('puppeteer');
const fs = require('fs');

const init = async () => {
    try {
        const browser = await puppeteer.launch({headless: true});
        const page = await browser.newPage();

        await page.setContent('<h1>Hello World</h1>');
        await page.emulateMediaType('screen');
        await page.pdf({
            path: 'hello-world.pdf',
            format: 'A4',
            printBackground: true,
            timeout: 0
        });

        console.info('PDF Generated');
        await browser.close();
        process.exit()

    } catch (error) {
        console.info(error)
    }
};

init()

после вызова метода page.pdf он ждет так долго и истекает время ожидания. ProtocolError: Page.printToPDF timed out. Increase the 'protocolTimeout' setting in launch/connect calls for a higher timeout if needed.

Но на моем MacBook Pro M1 это работает просто великолепно.

Попробовал это на виртуальной машине Windows 11 (Parallels) и паре ноутбуков с Windows 11. Но не повезло.

Что я здесь делаю не так? Нужно ли мне добавить что-то еще?

Спасибо!

Узел: v20.15.0

Кукловод: ^22.12.1

🤔 А знаете ли вы, что...
JavaScript позволяет создавать мобильные приложения для iOS и Android с использованием фреймворков, таких как React Native и NativeScript.


2
148
3

Ответы:

Через несколько часов мне удалось найти проблему.

После запуска браузера с журналированием браузера await puppeteer.launch({headless: true, dumpio:true}); было записано следующее:

[16848:6956:0703/000025.226:ERROR:sandbox_win.cc(913)] Sandbox cannot access executable. Check filesystem permissions are valid. See [URL]: Access is denied. (0x5)

DevTools listening on ws://[URL][16848:7356:0703/000025.488:ERROR:network_service_instance_impl.cc(600)] Network service crashed, restarting service.
[16848:6956:0703/000026.330:ERROR:sandbox_win.cc(913)] Sandbox cannot access executable. Check filesystem permissions are valid. See [URL]: Access is denied. (0x5)

поэтому мне удалось найти добавление args: ['--no-sandbox', '--disable-setuid-sandbox'] - это обходной путь, но не рекомендуется https://stackoverflow.com/a/53975412/9814969

const browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] }); сработало!

Кажется, это обычная проблема в системах на базе Linux, но я пробовал это в Windows. Поэтому добавив это как ответ


Решено

Основываясь на журнале io из вашего собственного ответа, я не уверен, что вы действительно смогли увидеть [URL], который он выводит на консоль, но он ведет к этой документации Chromium Sandbox , в которой указано, что вам, возможно, придется установить необходимые разрешения самостоятельно в зависимости от способа установки. Это может произойти при использовании Puppeteer в Windows. По сути, это также было скопировано в Устранение неполадок Puppeteer, где также можно установить необходимые разрешения с помощью icacls.

По моему мнению, это более безопасный способ, чем просто полное отключение песочницы. Однако SID, используемый в предоставленной команде S-1-15-2-1, приводит к ALL APPLICATION PACKAGES, что довольно широко. Вот почему в обоих документах упоминается, что «в средах с высоким уровнем безопасности следует использовать более строгий SID, например, идентификатор установщика» (я почти уверен, что предоставленная ссылка на установщик на самом деле ссылается на неправильный LOC и на самом деле должна вести до здесь ). Однако в документации Chromium Sandbox упоминается ALL RESTRICTED APPLICATION PACKAGES SID (Windows 10 RS2 или более поздняя версия), который не отображается в официальном списке Microsoft «Хорошо известных SID», но есть S-1-15-2-2.

Решение. Вот почему я думаю, что вместо отключения песочницы было бы безопаснее предоставить необходимые разрешения, выполнив следующую команду в CMD:

icacls %USERPROFILE%/.cache/puppeteer/chrome /grant *S-1-15-2-2:(OI)(CI)(RX)

Запуск cmd от имени администратора не требуется (по крайней мере, у меня). Путь — это место, где Puppeteer обычно хранит свои корзины Chrome, но вам может потребоваться изменить его, если вы указали другой путь в Puppeteer.

Дело в том, что S-1-15-2-2 по-прежнему является довольно широким SID, но мне не удалось найти более узкий SID, который бы работал. Если вы проверите установщик , вы увидите, что он устанавливает GENERIC_READ (GR) и FILE_DELETE_CHILD (DC) для SID AUTHENTICATED_USERS, однако этого не может быть всего, потому что LOC в "sandbox_win.cc" выдает вашу ошибку на самом деле проверяет GENERIC_READ (GR) и GENERIC_EXECUTE (GE) (всего (RX)). Я почти уверен, что идентификаторы безопасности пользователей и группы SID не будут работать. Я думаю, что подойдет SID для входа в систему, начинающийся с S-1-5-5-, но он будет меняться каждый раз. Я еще немного поиграюсь с информацией, найденной в этом ответе, и отредактирую его, если найду более безопасное решение. Кроме того, я даже не понимаю, почему SID пакетов работают, потому что они должны работать только для приложений Магазина Windows, процессов, запущенных в контейнере приложений или UWP. Так что это определенно не приложение из Магазина Windows. Я также проверил с помощью Process Explorer, и рассматриваемый процесс не запускается в контейнере приложения. Я не мог убедиться, что Chromium для Windows является UWP.


благодаря ответу @Fiddlesteaks мне пришлось запустить обе эти команды:

icacls $env:USERPROFILE/.cache/puppeteer/chrome-headless-shell /grant *S-1-15-2-2":(OI)(CI)(RX)"

icacls $env:USERPROFILE/.cache/puppeteer/chrome /grant *S-1-15-2-2":(OI)(CI)(RX)"

тогда генерация PDF работает без args: ['--no-sandbox', '--disable-setuid-sandbox']