Rails HTML Renderer - 一个用浏览器渲染图片/PDF 的微服务

Rei · 2023年11月18日 · 最后由 Rei 回复于 2023年11月18日 · 811 次阅读

之前我在一个应用用 Puppeteer 生成网页预览图,但把 chromium 打包进主应用导致镜像非常大,所以我一直想把渲染图片部分逻辑拆出去。

我对现有的方案做了一些调查,其中觉得最完善的是 https://github.com/browserless/browserless ,它把 chrome 放进进容器,提供 API 或者 DevTools Protocol 连接。可惜的是它用在闭源服务需要购买商业许可。

还有另一个项目 https://github.com/alvarcarto/url-to-pdf-api 似乎也不错,但我是几乎开发完才知道,就继续自己的项目了。如果你需要成熟的开源项目可以考虑前面提到的两个。

我觉得给 puppeteer 包装一个 REST 接口不是很难,并且能解决问题,所以自己做了一个。项目放在 https://github.com/chloerei/htmlrenderer ,以下介绍用法。

用法

启动服务:

docker run -p 3000:3000 --cap-add SYS_ADMIN ghcr.io/chloerei/htmlrenderer:latest

通过 URL 生成截图:

curl -X POST localhost:3000/screenshot \
  -H "Content-Type: application/json" \
  -o test.png \
  -d '{
    "url": "https://www.google.com"
  }'

通过 HTML 生成截图:

curl -X POST localhost:3000/screenshot \
  -H "Content-Type: application/json" \
  -o test.png \
  -d '{
    "html": "<h1>hello world</h1>"
  }'

生成 PDF:

curl -X POST localhost:3000/pdf \
  -H "Content-Type: application/json" \
  -o file.pdf \
  -d '{
    "url": "https://www.google.com"
  }'

基本上这只是 puppeteer 方法的包装,其他参数可以看项目文档和源码。

注意事项

  • 通过 puppeteer 可以轻易的让 chromuiom 执行 JavaScript 或者访问本地文件,这可能造成安全问题,所以应该把服务部署在内网,设置 ACCESS_TOKEN,并且只渲染可信的 URL 或 HTML。
  • 渲染时间取决于是否访问网络资源和 chromuiom 的性能,建议通过后台任务渲染图片。

其他

这个项目主要是自用,可能对别人有帮助所以开源出来。欢迎提 issue/pr,或者 fork 自己的版本。

cool 很棒的功能,不知道这个东西开销大不大,我记得凡事用 puppeteer 对系统配置要求都挺高,比较吃内存。

wangyanzi321 回复

占用我未测过。不过独立出去后,可以方便调整资源,例如 fly.io 可以设置一个容器一段时间没有请求就停止,有请求再启动。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号