后端【免费下载链接】url-to-pdf-apiWeb page PDF/PNG rendering done right. Self-hosted service for rendering receipts, invoices, or any content.项目地址https://gitcode.com/gh_mirrors/ur/url-to-pdf-api点击查看免费下载本文以仓库根目录 CHANGELOG.md 为骨架聚焦该项目两条核心版本记录1.0.0初始版本所提供的任意 URL / HTML 内容渲染为 PDF、PNG、JPEG、HTML的完整 API 能力以及其后针对:html输出的一项关键行为变更——从返回document.body.innerHTML调整为返回document.documentElement.innerHTML。读完本文你将掌握该微服务的输出模式差异、html 输出变更的底层源码依据以及如何在本地与 Heroku 上复现与验证这一行为。一、CHANGELOG 概述两行记录背后的技术要点仓库根目录下的 CHANGELOG.md 全文极简只包含两条记录未打版本号的最新变更将:html输出由原先的document.body.innerHTML改为document.documentElement.innerHTML1.0.0初始版本项目首个正式版本。虽然记录简短但这两条恰好对应了项目两个最值得理解的技术事实output参数支持pdf、screenshot、html三种输出模式其中html模式不是生成文件而是直接返回页面渲染后的 HTML 字符串html 输出抓取范围的界定方式经历过一次明确的语义修正由 body 到整个 documentElement这直接影响调用方拿到的 HTML 是否包含head内的样式、元信息与 title。下文将结合源码与测试用例把这两条记录展开为可验证、可实操的完整说明。二、核心变更详解:html输出为何从document.body改为document.documentElement2.1 变更内容与语义差异变更前变更后document.body.innerHTMLdocument.documentElement.innerHTML这两个表达式在浏览器 DOM 中的含义完全不同document.body只代表body元素。document.body.innerHTML只返回页面 body 内部的 HTML 片段不包含head中的title、meta、style、link等头部信息document.documentElement代表根元素html。document.documentElement.innerHTML返回整个 HTML 文档的序列化内容包括head与body的全部子孙节点更接近把整张页面抓下来的语义。对于需要拿到渲染后完整页面快照例如保存网页存档、把 HTML 再交给下游处理的调用方来说后者显然更合理——这正是该变更的意义所在。2.2 源码实现证据该变更在 src/core/render-core.js 中落地render()函数根据opts.output分派三种渲染分支if (opts.output pdf) { if (opts.pdf.fullPage) { const height await getFullPageHeight(page); opts.pdf.height height; } data await page.pdf(opts.pdf); } else if (opts.output html) { data await page.evaluate(() document.documentElement.innerHTML); } else { // screenshot 分支处理 clip / selector / fullPage 的联动 ... }可见html模式的核心实现就是一行page.evaluate(() document.documentElement.innerHTML)——在 Chrome 页面上下文中执行求值把渲染后的完整 DOM 序列化为字符串返回。CHANGELOG 记录的就是这一行从document.body到document.documentElement的替换。2.3 与 pdf、screenshot 模式的对比在 src/http/render-http.js 的getMimeType()中三种输出对应不同响应头if (opts.output pdf) { return application/pdf; } else if (opts.output html) { return text/html; } // screenshot: 依据 screenshot.type 返回 image/png 或 image/jpeg也就是说输出模式返回内容Content-Type典型用途pdfPDF 二进制application/pdf收据、发票、报表等正式文件screenshotPNG / JPEG 图片二进制image/png/image/jpeg网页快照、缩略图html渲染后的完整 HTML 字符串text/html抓取渲染结果、页面存档、继续加工需要强调的是html输出与输入 HTML 不是一回事输入html是渲染前的原始内容输出html是经过浏览器渲染、JS 执行、懒加载触发之后的完整文档序列化结果。三、1.0.0初始版本能力全景从 CHANGELOG 到完整 API1.0.0版本号背后是整套渲染微服务的初始能力这在 README.md 中有系统描述也与 src/core/render-core.js 的实现一一对应。3.1 渲染主流程源码级src/core/render-core.js 的render()是核心函数其执行顺序是合并默认参数viewport默认 1600×1200、goto.waitUntil默认networkidle0、pdf.format默认A4、printBackground默认true、screenshot.type默认png、screenshot.fullPage默认truecreateBrowser()启动 Headless Chromesrc/core/render-core.js使用--no-sandbox --disable-setuid-sandbox标志ignoreHttpsErrors透传给浏览器实例page.setViewport(opts.viewport)设置视口若emulateScreenMedia为真调用page.emulateMedia(screen)——这正是 README 中默认忽略media print规则的底层原因根据html是否字符串调用page.setContent(html, opts.goto)或page.goto(url, opts.goto)若设置waitFor调用page.waitFor(numOrStr)数字为毫秒、字符串为 CSS 选择器若设置scrollPagetrue执行scrollPage(page)逐步滚屏以触发懒加载src/core/render-core.js以半个视口高度为步长、400px 底部阈值、30 秒超时按output分派 pdf / html / screenshot 三种渲染finally中关闭浏览器调试模式除外。3.2 三种请求入口src/router.js 暴露了三个路由GET /api/render所有参数走 query string采用点号记法如?pdf.scale2url为必填POST /api/renderJSON body参数放入 JSON 对象支持嵌套的viewport、goto、pdf、screenshot、cookies等结构POST /api/rendertext/html bodyHTML 作为请求体其余参数仍走 query stringGET /healthcheck健康检查返回 200OK。参数在校验层src/util/validation.js被严格约束例如url必须是http/httpsURIwaitFor允许 1~60000ms 数字或长度 1~2000 的字符串screenshot.selector必须匹配#/.开头的 CSS 选择器output仅限pdf/screenshot/html三值。3.3 环境变量与部署配置src/config.js 是全部环境变量的唯一入口均做了类型转换环境变量作用PORT服务端口默认9000ALLOW_HTTP设为true时跳过 HTTPS 强制src/app.js 默认要求 HTTPSDEBUG_MODE调试模式有头 Chrome、250ms sloMoDISABLE_HTML_INPUT设为true时禁止 HTML 输入渲染返回 403CORS_ORIGIN跨域来源默认*BROWSER_WS_ENDPOINT连接已运行的 Chromepuppeteer.connectBROWSER_EXECUTABLE_PATH自定义 Chrome 可执行文件路径API_TOKENS逗号分隔的 token 列表设置后强制x-api-key请求头认证src/router.jsALLOW_URLS逗号分隔的 URL 白名单支持host:、regex:前缀与普通 URL 精确匹配src/http/render-http.js其中ALLOW_URLS与DISABLE_HTML_INPUT是安全关键配置。需要特别提醒README 原文明确警告不要将本 API 直接暴露到公网因为它允许调用方在服务器上的 Chrome 会话中执行任意 JavaScript存在泄露服务器文件内容的风险。3.4 常用参数速查GET 点号记法以下是 README 与校验 schema 共同确认的常用参数及其取值约束可直接用于实战参数类型/取值说明url必填http/https要渲染的 URLoutputpdf/screenshot/html输出格式emulateScreenMediaboolean默认true模拟media screen而非 printenableGPUboolean默认false启用 Chrome GPUWindows 下恒为 falseignoreHttpsErrorsboolean默认false忽略 HTTPS 证书错误scrollPageboolean默认false渲染前滚屏触发懒加载waitFor数字(ms) 或 CSS 选择器渲染前等待attachmentNamestring设置content-disposition附件名viewport.width/height数字1~30000视口尺寸默认 1600×1200viewport.deviceScaleFactor数字0~100设备缩放因子dprgoto.timeout数字0~60000导航超时默认 30000ms0 为禁用goto.waitUntilload/domcontentloaded/networkidle0/networkidle2导航完成判定默认networkidle0pdf.scale数字0~1000页面缩放默认 1pdf.printBackgroundboolean打印背景图形源码默认truepdf.landscapeboolean横向纸张pdf.pageRangesstring页码范围如1-5, 8, 11-13pdf.formatstring默认A4纸张格式优先于宽高pdf.width/height带单位字符串自定义纸张宽高pdf.margin.top/right/bottom/left带单位字符串页边距pdf.fullPageboolean单页输出整个页面pdf.headerTemplate/footerTemplatestring页眉页脚模板Puppeteer 目前基本只支持单行文本需配合 marginCSS 才能显示screenshot.fullPageboolean默认true整页截图screenshot.typepng/jpeg图片格式默认pngscreenshot.quality0~100 整数JPEG 质量screenshot.omitBackgroundboolean隐藏默认白底、支持透明screenshot.clip.x/y/width/height数字裁剪区域screenshot.selector#/.开头的选择器只截取匹配元素一个值得注意的源码细节在 src/core/render-core.js 中当用户显式设置了pdf.width与pdf.height或pdf.fullPage时会主动删除pdf.format默认值因为format会覆盖宽高。这与 README 中format 优先于 width/height的说明互为印证。四、用测试用例验证变更与初始版本能力test/test-all.js 使用 Mocha Supertest pdf-parse对 API 行为做集成验证可以作为理解本文主题的旁证HTML 渲染输入html in json body should succeed与html as text body should succeed两个用例分别验证 JSON body 与text/html请求体两种 HTML 输入方式断言响应为application/pdf且内容长度大于 40KBtest/test-all.jsCookie 注入cookies should exist on the page用例向页面注入两个 Cookie并从生成的 PDF 文本中校验Number-of-cookies-received-2等字符串对应 src/core/render-core.js 通过 CDP 会话Network.setCookies设置 Cookie 的实现HTTPS 错误处理invalid cert should not cause an error when ignoreHttpsErrorstrue验证ignoreHttpsErrors参数确实生效test/test-all.js特殊字符渲染special characters should be rendered correctly验证 PDF 中能正确还原ä ö ü等字符test/test-all.js。虽然当前测试套件中没有直接断言document.documentElement.innerHTML内容的用例但 html 输出分支在 src/core/render-core.js 的实现与 CHANGELOG 记录完全一致这是本变更最直接的代码级证据。你可以通过npm install npm start在本地package.json 定义了启动脚本启动服务后用如下命令直观对比变更前后的输出差异# 获取 html 输出当前行为完整文档含 head curl -XPOST -d{html: htmlheadstylep{color:red}/style/headbodyphi/p/body/html} \ -Hcontent-type: application/json http://localhost:9000/api/render?outputhtml响应中应能看到html内的head与body全部内容若按变更前的行为head部分会被丢弃。五、如何深入验证与扩展阅读变更本体查看 CHANGELOG.md 与 src/core/render-core.js三种输出模式的 MIME 与响应处理src/http/render-http.js参数白名单与类型约束src/util/validation.js环境变量与安全开关src/config.js、src/router.js本地部署与示例README 的 Development 小节与 docs/local-examples.md 提供了本地curl示例如以test/resources/large-linked.html作为text/html请求体渲染 PDF。自检结论本文以 CHANGELOG 的两条记录为骨架完整继承了其html 输出变更与1.0.0 初始版本两个核心信息点并借助 README、render-core.js、validation.js、test-all.js 等仓库证据进行了源码级扩充所有结论均可回溯到当前仓库对应文件未引入任何未经证实的外部数据。赞分享后端【免费下载链接】url-to-pdf-apiWeb page PDF/PNG rendering done right. Self-hosted service for rendering receipts, invoices, or any content.项目地址https://gitcode.com/gh_mirrors/ur/url-to-pdf-api点击查看免费下载相关推荐从 1.0.0 到 5.16.7loadable-components 版本演进与 API 变迁全景解读从 1.0.0 到 5.16.7loadable components 版本演进与 API 变迁全景解读 本文以本仓库根目录的 CHANGELOG.md ht前端MediaElementJS 版本历史全景从 1.0.0 到 7.0.7 的演进里程碑与重大变更解读MediaElementJS 版本历史全景从 1.0.0 到 7.0.7 的演进里程碑与重大变更解读 changelog.md https://link.gi音视频前端UI组件JAX 版本演进与变更日志深度解读从 0.1.58 到 0.11 的 API 演进全景JAX 版本演进与变更日志深度解读从 0.1.58 到 0.11 的 API 演进全景 JAX 是面向 Python NumPy 程序的可组合变换框架自人工智能机器学习深度学习编译器高性能计算上一篇TradingAgents-CN 聚合渠道环境变量配置完全指南从 .env 到自动启用的一站式接入下一篇Envoy 访问日志 JSON 格式化修复omit_empty_values 从失效到真正生效的完整解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考