Решил я добавить в
PersMarket возможность
скачивать PDF вакансий и резюме. Задача звучит несложно, но оказалось, что не всё так банально.
Как мы делали раньше такие вещи?
На бэкенде с помощью сторонних библиотек (
Dompdf,
mPDF) генерили документ и отдавали клиенту сырые данные с указанием
Content-Type = application/pdf
Однако, такие документы плохо поддерживают современный CSS и имеют проблемы со шрифтами.
Еще, кстати, был вариант использвать wkhtmltopdf, но это может блокировать выполнение скрипта надолго.
Чтобы PDF был такой же красивый, как страница на фронтенде, лучше всего и генерировать браузером.
Я провел консультативную сессию с несколькими нейросетями, и они отговорили меня от генерации чисто на фронтенде (
jsPDF,
html2pdf). Говорят, PDF будет "плыть", стили ломаться, и серверную логику не добавить.
В итоге мы с ними нашли интересный вариант - генерация через
headless-браузер.
Как это работает?
Поскольку у меня Docker-сонтейнеры, я добавил еще один контейнер, внутрь которого положил Node.js-скрипт. Он умеет отображать страницы сервиса у себя внутри в браузере
Chromium без пользовательского интерфейса (headless). Работает через
Puppeteer. По запросу фронтенда бэкенд идет в PDF-сервис и просит конкретную страницу. После рендера страницы она сохраняется в PDF и отдается бэкенду, а он пересылает ее клиенту.
Страница получается точно такая же, как в браузере, со всеми стилями и даже эмоджи.
В общем, всё получилось, и, на мой взгляд, вполне прилично. Пришлось повозиться с пробросом аутентификации, но все вопросы решились. Далее это всё можно обкладывать очередями, кэшами, rate-limiter-ами и т.д.
А ведь headless-браузер можно использовать и в быту. Например:
- автоматические e2e-тесты в CI/CD-пайплайнах
- автоматический веб-скрейпинг
- генерация скриншотов страниц и всякое такое
#web #persmarket