跳转到内容

NextPDF Cloudflare 边缘渲染桥接概览

nextpdf/cloudflare 是一个边缘渲染桥接。你的 PHP 应用持有 HTML,而 Cloudflare Worker 持有无头浏览器。该桥接通过 HTTPS 将 HTML 发送给 Worker,并接收其返回的已渲染 PDF 字节。你的 PHP 进程内不会运行无头浏览器,桥接负责的路径上也不需要本地 Chromium 二进制文件。

该软件包属于 NextPDF 生态系统,并依赖于 nextpdf/core^3.0。它是线路协议层代码:构建 JSON 请求、校验输入和目标地址、通过 PSR-18 客户端发送请求,并将响应解析为一个带类型的结果对象。Worker 实现本身并不属于此软件包。该桥接与你部署的 Worker 通信。

该桥接最关键的特征在于:HTML 会跨越网络边界,到达一个你无法直接控制的浏览器引擎。软件包中的每一项安全控制,都是围绕这条边界设计的。

  • HTML 会在离开 PHP 进程之前被校验(CloudflareSecurityPolicy::validate())。
  • 目标 URL 会在请求发送之前被校验(CloudflareSecurityPolicy::validateWorkerUrl()),并在发起请求时重新校验,以关闭 time-of-check/time-of-use 窗口(assertPinsStillValid())。
  • 传输层可以钉定解析出的 IP 集合以及服务器证书公钥(Transport\PinnedCurlTransport)。

如果你正在评估该桥接是否用于生产环境,请先阅读 /integrations/cloudflare/security-and-operations/,再阅读 /integrations/cloudflare/quickstart/。这套安全模型并不是附加项,而是此软件包被设计成当前形态的原因。

能力支撑实现
通过 Cloudflare Worker 将 HTML 渲染为 PDFCloudflareHtmlRenderer::render()
可达性探测(HTTP HEADCloudflareHtmlRenderer::isAvailable()
与厂商无关的传输层注入 PSR-18 ClientInterface
输入加固(大小、base64 炸弹、meta-refresh)CloudflareSecurityPolicy::validate()
SSRF / DNS 重绑定防御CloudflareSecurityPolicy::validateWorkerUrl() + assertPinsStillValid()
TLS 公钥钉定、cURL 层 DNS 钉定Transport\PinnedCurlTransport
Worker 不可达时回退到本地 ChromeContract\LocalRendererFactoryInterface
二进制和 JSON(base64)响应解析CloudflareResponseParser
边缘遥测(渲染时间、边缘节点位置、内容高度)CloudflareRenderResult
来自 R2 存储桶的自定义字体CloudflareRenderPayloadr2FontBucketfontFiles
API 保护层(密钥认证、负载大小、限流)ApiProtection
通过兼容 S3 的 API 将 PDF 归档到 R2R2ArchiveManager

每一行都映射到 NextPDF\Cloudflare 命名空间中的一个类。每一行也都是围绕该类的行为及其测试来验证的,而不是针对某份规范文档。

  • 它不会运行浏览器。运行浏览器的是 Worker。
  • 它不会部署或配置你的 Worker。该产物由你负责。
  • 它不会为 PDF 签名。签名属于 nextpdf/core 或商业版的范畴。需要签名时,先渲染,然后用引擎对返回的字节进行签名。NextPDF Pro 提供 PAdES B-B 签名。长期验证(long-term-validation)配置文件是 Enterprise 版的能力。
  • 它不会对任何 Cloudflare 平台容量或限制做出断言。本文档陈述的唯一一组大小与时间限制,是此软件包在自身配置中强制执行的那些限制(参见 /integrations/cloudflare/configuration/)。

该桥接承载着两套截然不同但互为补充的策略;把它们混为一谈,是最常见的评审错误。下面分别介绍每一套。

  • HTML 安全策略HtmlSecurityPolicyInterface,默认为 NextPDF\Html\DefaultHtmlSecurityPolicy,由 nextpdf/core 提供):解析层的内容过滤,会在内容到达 Worker 之前应用。通过 getHtmlSecurityPolicy() 获取它。
  • Cloudflare 安全策略CloudflareSecurityPolicy,静态):传输层关注点:输入大小、base64 解压炸弹检测、meta-refresh 拦截、HTTPS 强制,以及对 Worker URL 的 SSRF / DNS 重绑定防御。

渲染器自身的文档块(docblock)已经说明了这种分离。本页重述它,是因为生产环境评审者需要在同一屏上看到这两个名称。

单次 render() 调用会执行以下可观察序列。该序列直接来自 CloudflareHtmlRenderer::render()

  1. 配置完整性检查(workerUrlapiToken 非空)。失败时,桥接要么回退到本地渲染器,要么抛出 CloudflareNotAvailableException
  2. 按已配置的最大大小、base64 URI 上限以及 meta-refresh 禁令校验 HTML。
  3. 校验 Worker URL,解析主机并返回经审核的 IP 集合。
  4. 构建负载(CloudflareRenderPayload)。
  5. 在使用时刻重新检查主机的 DNS 应答,确认其自第 3 步以来没有变化。
  6. 发送 HTTP POST:当存在 IP 集合或 SPKI 钉定集合并且提供了 PSR-17 ResponseFactory 时,通过钉定的 cURL 传输层发送;否则通过注入的 PSR-18 客户端发送。
  7. 将响应解析为一个 CloudflareRenderResult

CloudflareRenderException 之外,任何可抛出对象都会触发回退路径。CloudflareRenderException(来自 Worker 的 HTTP 错误或格式错误的响应)会原样重新抛出。这是 Worker 端失败,而不是可达性失败,因此不会回退。

  • /integrations/cloudflare/install/ — 安装该软件包和一个 PSR-18 客户端。
  • /integrations/cloudflare/configuration/ — 每个配置字段及其经源码核实的默认值。
  • /integrations/cloudflare/quickstart/ — 可运行的首次渲染示例。
  • /integrations/cloudflare/production-usage/ — 回退、遥测、R2 归档和 API 保护。
  • /integrations/cloudflare/security-and-operations/ — 信任边界的运维细节。
  • /integrations/cloudflare/troubleshooting/ — 失败模式和异常映射。
  • /integrations/cloudflare/boot-and-discovery/ — 该桥接如何接入宿主框架。
  • /integrations/cloudflare/integration/ — 通过 Cloudflare 服务驱动 NextPDF。