最近给 Inkstone 配置访问入口时,我碰到了一个问题:应用已经部署到 Cloudflare Workers,使用的是 inkstone.dingzihang001220.workers.dev,但国内访问不顺利。我用 ITDOG 测试时,国内节点一片红。
后来将 inkstone.dingzh.cc 接入阿里云 ESA,再由 ESA 回源到原来的 Worker。同样做国内多地测试,新入口变成了全绿。
这篇文章记录这套接入方法。Inkstone 是案例,配置思路也可以用于其他以 Workers 提供 HTTP 服务的应用。部署位置保持在 Cloudflare,给访客使用的入口则换成自己的域名。
请求经过了哪些地方
两种访问方式的差别,在于浏览器先与谁建立连接:

浏览器与 ESA 建立连接,ESA 再向 Worker 获取响应。对于允许缓存的资源,ESA 还可以在边缘节点复用缓存;页面和接口即使没有命中缓存,也会经过这条代理链路。
因此,这次“能不能访问”的变化,主要观察的是入口和访问路径。不能只因为接入了 ESA,就把所有改善都归因于缓存,也不能仅凭一次测速确定原域名访问失败的具体原因。
Cloudflare 本身也建议生产应用使用 Workers Route 或 Custom Domain,而不是长期把 workers.dev 当作生产入口[1]Cloudflare Workers 的路由与域名参考资料。本文介绍的是在应用前面增加 ESA 入口的方案,案例仍保留 workers.dev 作为可用源站;如果以后更换源站域名,还需要同步修改回源配置。
接入前准备
需要先有一个能正常响应请求的 Worker,以及一个自己控制 DNS 的域名。接入前,最好在能够访问源站的网络环境中确认:原来的页面、接口和静态资源本身可以工作。这样后续遇到错误时,才能区分应用故障与代理配置问题。
ESA 的加速区域也要提前选好:
| 加速区域 | ICP 备案要求 |
|---|---|
| 中国内地 | 域名需要具备中国 ICP 备案 |
| 全球,包含中国内地 | 域名需要具备中国 ICP 备案 |
| 全球,不含中国内地 | 不要求中国 ICP 备案 |
区域决定可以使用哪些节点。“国内用户能访问”与“请求落到中国内地节点”是两个不同的判断,前者需要实际测试,后者要看站点选择的服务区域。接入方式、套餐和区域支持情况以控制台及官方文档为准[2]ESA 站点接入与服务区域参考资料。
下面统一用这组示例讲配置,操作时替换为自己的值:
| 用途 | 示例 |
|---|---|
| ESA 站点 | example.com |
| 提供给访客的地址 | app.example.com |
| Worker 源站 | demo.account.workers.dev |
将自有域名接入 ESA
选择 DNS 接入方式
在 ESA 控制台添加站点。根域名作为站点名称,便于统一管理其下的子域名。
接入方式主要有 NS 和 CNAME 两种:NS 接入需要调整域名的权威 DNS;CNAME 接入可以保留现有 DNS 服务商,再将需要代理的域名指向 ESA 分配的接入地址。我这次已有域名和 DNS 配置,采用的是控制台提供的 CNAME 接入方式。
按照控制台完成站点所有权验证后,在 DNS → 记录 中添加业务记录:
| 字段 | 填写内容 |
|---|---|
| 记录类型 | CNAME |
| 主机记录 | app |
| 代理状态 | 开启代理加速 |
| 记录值/源站类型 | 域名 |
| 源站域名 | demo.account.workers.dev |
| 回源 Host | 跟随源站域名 |
源站填写主机名,不包含 https:// 和路径。原 Worker 若有 /api/notes 这样的接口,正常代理时仍通过 https://app.example.com/api/notes 访问,不需要把 /api/notes 填进源站域名。
分清两个 CNAME 的用途
CNAME 接入最容易混淆的地方,是这里有两层配置。ESA 的业务记录决定向哪里回源;原 DNS 服务商的解析记录决定访客先访问哪里:
| 配置位置 | 填写的目标 |
|---|---|
| ESA 的业务记录 | demo.account.workers.dev |
| 原 DNS 服务商的解析记录 | ESA 为 app.example.com 分配的接入 CNAME |
在原 DNS 服务商那里,应复制 ESA 控制台分配的完整接入 CNAME。不能把示例 Worker 域名直接当作 ESA 接入 CNAME,否则访客的解析链路仍没有指向 ESA。
如果采用 NS 接入,则按 ESA 的 NS 接入流程完成解析管理,无需再机械套用上述外部 DNS 操作。两种方式的具体流程见 ESA 的 DNS 入门说明[3]ESA DNS 接入与业务记录参考资料。
配置访问域名的证书
为 app.example.com 配置有效的边缘 HTTPS 证书,等待控制台显示可用。访客连接 ESA 时,校验的是这个访问域名的证书。
随后配置 HTTP 跳转 HTTPS,并实际访问一次,确认没有跳转循环。这一段连接与 ESA 到 Worker 的回源连接分开配置,边缘证书可用,并不等于回源参数也已经正确。
配置 HTTPS 回源、Host 与 SNI
三个域名字段分别负责什么
对这套拓扑,可以先把源站地址、回源 Host 与回源 SNI 都明确设为 demo.account.workers.dev。三个字段的职责不同:
| 字段 | 用途 |
|---|---|
| 源站地址 | 决定 ESA 连接到哪里 |
| 回源 Host | 决定 HTTP 请求交给源站上的哪个站点 |
| 回源 SNI | 在 TLS 握手时告诉源站使用哪个域名的证书 |

访问域名仍然是 app.example.com。浏览器地址与回源 Host 不必相同;这里的目标,是让 ESA 按 Worker 原来的域名请求源站。回源规则还可以独立指定协议和端口[4]ESA 回源规则支持的配置参考资料。
ESA 默认的回源 SNI 与回源 Host 相同,所以不一定每次都要单独添加 SNI 配置。我这次在规则中显式填写了它,便于确认最终值,也避免受其他继承设置影响。SNI 在 HTTPS 握手阶段生效,单独改 HTTP Host 并不能修正错误的 SNI[5]ESA 回源 SNI 的含义与默认值参考资料。
创建只匹配当前应用的回源规则
在 规则 → 回源规则 中添加规则,匹配条件写成当前业务域名:
1 | (http.host eq "app.example.com") |
执行配置如下:
| 配置项 | 值 |
|---|---|
| 回源 Host | demo.account.workers.dev |
| 回源协议 | HTTPS |
| HTTPS 端口 | 443 |
| 回源 SNI | demo.account.workers.dev |
同时保留源站证书合法性校验。正常的 Workers HTTPS 源站应提供可验证的证书,配置问题应从域名、SNI 和协议等参数排查。
如果一个 ESA 站点下还有博客、图片站等其他服务,条件中要明确主机名。检查已有规则是否也匹配当前域名,尤其留意排在前面的通配规则,避免把应用请求送到另一个源站。
Inkstone 的实际配置
我的配置与上面的示例一一对应:
| 配置项 | 实际值 |
|---|---|
| 访问域名 | inkstone.dingzh.cc |
| 源站域名 | inkstone.dingzihang001220.workers.dev |
| 回源 Host | inkstone.dingzihang001220.workers.dev |
| 回源 SNI | inkstone.dingzihang001220.workers.dev |
| 回源协议与端口 | HTTPS,443 |
| 源站证书校验 | 开启 |
这里保留了 Worker 原来的入口。后续若要关闭 workers.dev,需要先提供另一个可用的源站地址并调整 ESA,不能只关闭旧入口而不改回源配置。
缓存策略先遵循源站
对动态应用,我更倾向于先让源站表达缓存要求,再按资源类型补充优化。
这次 Inkstone 没有新增专属 ESA 缓存规则。站点的全局设置是:浏览器缓存遵循源站;边缘缓存优先遵循源站,否则使用默认策略;查询字符串全部保留。其他博客规则都限定了博客自己的主机名,不会匹配 Inkstone。
“没有专属规则”仍然有默认行为。常见静态后缀的 GET、HEAD 请求可以进入 ESA 缓存流程;HTML、目录页面和一般无后缀动态接口默认回源。浏览器是否保存、多久复用,则继续由响应头决定[6]ESA 默认缓存类型与生效逻辑参考资料。
可以按下面的思路检查应用:
| 内容 | 缓存要求 |
|---|---|
| HTML 入口 | 每次使用前验证新鲜度,例如 no-cache 或 max-age=0, must-revalidate |
| 会话、私有笔记等接口 | 使用 no-store,避免存储这类响应 |
| 带内容哈希的 JS、CSS | 文件内容变化时 URL 也变化,可设置较长缓存 |
| 没有版本标识的文件 | 根据实际更新方式确定时长,避免更新后长时间复用旧内容 |
Workers 静态资源默认会返回 public, max-age=0, must-revalidate,并配合 ETag。这表示内容可以保存,但再次使用前要验证;验证未变化时可以返回 304,不必重新下载整个文件[7]Cloudflare Workers 静态资源响应头参考资料。
Inkstone 的首页和抽查的 JS、CSS 正是这套策略。首页在 ESA 上显示为 DYNAMIC,部分静态资源显示为 REVALIDATED;后者表示边缘缓存已通过回源校验,而非每次都完整下载。
如果构建输出目录中的资源都带内容哈希,可以在 Workers 项目的静态资源目录加入 _headers,例如:
1 | /assets/* |
这条示例只适合满足“内容改变就换 URL”的静态目录。_headers 要随静态资源一起部署,不能放在不会上传的目录;它也不负责 Worker 代码动态生成的接口响应,接口仍应由应用设置响应头。
这属于后续性能优化。应用若有 SW,命中其本地资源缓存时也可以直接复用文件。无需为了节省一条规则,把动态应用直接并进博客强制 no-cache 的配置;同一缓存规则中的匹配分支会共用所配置的动作。
如何验证接入是否有效
先看页面和响应头
用浏览器打开新域名,确认页面内容、脚本和样式都能加载。再查看 HTTP 是否跳转 HTTPS,证书是否有效,以及请求有没有跳回 workers.dev。
也可以使用下面的命令观察一次实际 GET 响应。在 Windows PowerShell 中使用 curl.exe,避免与旧版 PowerShell 的同名别名混淆:
1 | curl -sS -D - -o /dev/null https://app.example.com/ |
1 | curl.exe -sS -D - -o NUL https://app.example.com/ |
重点关注状态码、Location、Cache-Control、Content-Type 和 X-Site-Cache-Status。动态页面返回 DYNAMIC 可以是正常结果,不能把“没有命中边缘缓存”直接判为代理没有生效。
2026 年 11 月 3 日检查 Inkstone 时,观察到的结果如下。这些是单独进行的线上响应检查,与开头那次国内多地测速分别记录:
| 请求 | 状态码 | 缓存头 | ESA 状态 |
|---|---|---|---|
首页 / | 200 | public, max-age=0, must-revalidate | DYNAMIC |
/api/auth/session,匿名请求 | 200 | no-store | DYNAMIC |
/api/notes,未登录 | 401 | no-store | DYNAMIC |
| 抽查的带哈希 JS、CSS | 200 | public, max-age=0, must-revalidate | REVALIDATED |
登录页也能正常呈现。未登录访问私有笔记返回 401 符合预期,这一步不代表已经验证了登录后的保存、上传等操作。
再做国内多地测试
用 ITDOG 这类工具,分别测试原 workers.dev 地址和新入口,尽量保持测试方式、节点范围与时间接近。保留测试记录,比较成功率和耗时;如果只做了 Ping 或 TCP 连接测试,还需要补充 HTTP 和浏览器检查。
我这次观察到的变化,是原 Workers 默认域名在测试的国内节点全红,经过 ESA 的自有域名全绿。这个结果可以说明这次接入改善了所测节点的可达性,但不能直接推广为所有地区、所有运营商和以后每次访问都一样。
实际应用还应继续检查登录、Cookie、写入接口和文件上传。如果应用用到了 SSE、WebSocket 或其他长连接,也要单独测试。涉及 OAuth 回调、固定公开地址或来源校验时,需要在应用和相关服务中检查新域名是否已被允许。
出现错误时,按请求链路排查
| 现象 | 优先检查 |
|---|---|
| 新域名无法解析,或流量没有经过 ESA | 站点验证、权威 DNS、ESA 分配的接入 CNAME、代理状态 |
| 浏览器提示访问域名证书错误 | ESA 边缘证书的域名范围与生效状态 |
| ESA 提示回源连接或 TLS 错误 | 源站可达性、HTTPS 443、回源 SNI、Host、源站证书 |
| 出现错误站点或意外 404 | 源站地址、回源 Host、覆盖当前域名的其他规则 |
| 页面打开了,但登录、跳转或接口异常 | Cookie 域、回调地址、来源校验、应用公开地址配置 |
| 发布后仍加载旧界面 | HTML 响应头、源站版本、ESA 缓存、浏览器缓存和应用自己的 SW |
先定位问题发生在哪一段,再调整对应设置,比同时改解析、证书和缓存更容易确认原因。
适用场景与取舍
这套方法适合已经运行在 Workers 上、希望保留现有应用部署,同时增加自有域名访问入口的 HTTP 服务。它为访问链路增加了 ESA 这一层,也带来了对应的运维工作:域名、证书、回源规则、缓存与应用回调都需要保持一致。
预算上,要分别查看 ESA 套餐的服务区域、流量与功能额度,以及 Workers 自己的请求、计算和存储用量。接入 ESA 后,动态请求依然可能继续到达 Worker,不能据此认为 Cloudflare 一侧的消耗已经消失。
我这次主要收获是:Workers 上已经能工作的应用,可以通过额外的代理入口改善某些网络环境下的访问。把 DNS 的两层目标、HTTPS 回源和域名参数配置清楚,再用实际请求和多地测试确认效果,这套接入才算跑通。











