静态网站托管在 Cloudflare Pages 或 GitHub Pages 上确实省心,但遇到需要处理表单提交、查询 IP 归属地、或者做个简单的访问计数器时,纯静态页面就束手无策了。这时候,Cloudflare Workers 就是一个零成本、零服务器维护的解决方案。
这篇文章是我从2025年开始使用 Workers 的真实经验总结。我会跳过官方文档里那些让你犯困的概念,直接带你从安装工具到写出第一个能跑在生产环境的 API,全程大概需要 20 分钟。所有代码都经过实际测试,基于 2026 年 7 月最新的 Wrangler 3.x 版本。
一、为什么静态站需要 Workers
先说说我的实际场景。我手上有十几个单页工具站,全部托管在 Cloudflare Pages 上。大部分功能用前端 JavaScript 就能搞定,但有几个需求是前端做不到的:
- IP 查询工具:需要调用后端接口获取 IP 的地理位置信息,但我不想单独租一台服务器。
- 留言表单:用户提交的数据需要被存储或转发到邮箱,静态页面没法直接处理 POST 请求。
- 访问计数器:想统计每个工具站的访问次数,但又不想引入第三方统计的隐私风险。
- API 代理:有些第三方 API 不支持跨域(CORS),需要一个中间层帮忙转发请求。
这些需求都不复杂,传统做法是租一台 VPS,装个 Nginx,写几行 PHP 或 Node.js。但维护服务器、处理安全更新、应付流量波动,对个人站长来说成本太高了。
Workers 的核心价值:它让你的代码运行在 Cloudflare 全球 300 多个边缘节点上,用户请求在哪,代码就在哪执行。延迟极低,免费额度对个人项目完全够用,而且不需要管理任何服务器。
二、Workers 到底是什么
用最直白的话说,Cloudflare Workers 是一个在边缘节点运行 JavaScript 代码的无服务器(Serverless)平台。它基于 V8 引擎,支持标准的 Web API(如 fetch、Request、Response),所以你写的代码和浏览器里的 JavaScript 非常像。
几个关键特点:
- 冷启动几乎为零:代码已经部署在全球边缘节点上,不需要像传统 Serverless 那样等容器启动。
- 免费额度 generous:每天 10 万次请求,每次请求 CPU 时间 10 毫秒(对简单 API 来说根本用不完)。
- 原生支持 KV 存储:可以存简单的键值对数据,比如计数器、配置项等。
- 和 Pages 深度集成:同一个项目里可以同时有静态页面和 Workers 函数,路由自动分配。
三、准备工作:安装 Wrangler CLI
Wrangler 是 Cloudflare 官方提供的命令行工具,用来创建、开发和部署 Workers。你需要先确保本地安装了 Node.js(建议 18 以上版本),然后全局安装 Wrangler:
# 使用 npm 安装
npm install -g wrangler
# 或者使用 pnpm
pnpm add -g wrangler
安装完成后,登录你的 Cloudflare 账号:
wrangler login
这条命令会打开浏览器,让你授权 Wrangler 访问你的 Cloudflare 账号。授权成功后,命令行会显示你的账号信息。
提示:如果你之前用过旧版 Wrangler(v1 或 v2),建议先卸载再安装最新版:npm uninstall -g @cloudflare/wrangler wrangler,然后重新执行 npm install -g wrangler。v3 版本的配置格式和命令有一些变化。
四、第一个 Worker:Hello World
先做一个最简单的 Worker,验证环境是否配置正确。创建一个新目录,初始化项目:
mkdir my-first-worker
cd my-first-worker
wrangler init --yes
提示:Wrangler 3.x 仍支持 wrangler init,但官方最新推荐用 npm create cloudflare@latest 创建项目,模板更新更及时。
这个命令会生成一个基础项目结构,包含 wrangler.toml 配置文件和 src/index.js 入口文件。打开 src/index.js,把内容改成下面这样:
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
// 简单的路由判断
if (url.pathname === "/api/hello") {
return new Response(JSON.stringify({
message: "Hello from Cloudflare Workers!",
time: new Date().toISOString(),
region: request.cf?.colo || "unknown"
}), {
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
}
});
}
return new Response("Not Found", { status: 404 });
}
};
这段代码做了三件事:
- 解析请求的 URL,判断路径是否为
/api/hello。 - 如果是,返回一个 JSON 响应,包含问候语、当前时间和用户请求所在的 Cloudflare 数据中心代码(
request.cf.colo)。 - 如果不是,返回 404。
本地测试一下:
wrangler dev
命令会启动一个本地开发服务器,默认在 http://localhost:8787。打开浏览器访问 http://localhost:8787/api/hello,你应该能看到返回的 JSON 数据。
五、实战:给静态站加一个访问计数器 API
Hello World 跑通后,我们来做一个真正有用的东西:一个访问计数器 API。这个功能在很多工具站里都能用到,比如显示"本站已被访问 X 次"。
5.1 创建 KV 命名空间
计数器需要持久化存储,Workers 提供了 KV(Key-Value 存储)。先在 Cloudflare 控制台或通过命令行创建一个 KV 命名空间:
wrangler kv:namespace create "COUNTER_STORE"
命令会返回一个 ID,类似 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx。把这个 ID 复制下来,添加到 wrangler.toml 配置文件中:
name = "my-first-worker"
main = "src/index.js"
compatibility_date = "2026-07-25"
[[kv_namespaces]]
binding = "COUNTER_STORE"
id = "你的KV命名空间ID"
5.2 编写计数器逻辑
修改 src/index.js,增加计数器路由:
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const path = url.pathname;
// 处理 CORS 预检请求
if (request.method === "OPTIONS") {
return new Response(null, {
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type"
}
});
}
// 访问计数器 API
if (path === "/api/counter") {
const key = url.searchParams.get("key") || "default";
// 从 KV 读取当前计数
let count = await env.COUNTER_STORE.get(key);
count = count ? parseInt(count) : 0;
// 增加计数
count++;
await env.COUNTER_STORE.put(key, count.toString());
return new Response(JSON.stringify({
key: key,
count: count,
updated: new Date().toISOString()
}), {
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
}
});
}
// 获取计数(只读,不增加)
if (path === "/api/counter/get") {
const key = url.searchParams.get("key") || "default";
let count = await env.COUNTER_STORE.get(key);
count = count ? parseInt(count) : 0;
return new Response(JSON.stringify({
key: key,
count: count
}), {
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
}
});
}
return new Response("Not Found", { status: 404 });
}
};
5.3 在静态页面中调用
在你的静态 HTML 页面里,用几行 JavaScript 就能调用这个 API:
<!-- 显示访问次数 -->
<div id="visit-count">加载中...</div>
<script>
// 页面加载时获取计数
fetch('https://你的Worker域名/api/counter?key=homepage')
.then(res => res.json())
.then(data => {
document.getElementById('visit-count').textContent =
'本站已被访问 ' + data.count + ' 次';
})
.catch(err => {
document.getElementById('visit-count').textContent = '统计暂不可用';
});
</script>
注意:KV 存储是最终一致性的,写入后在全球所有节点完全同步可能需要几十秒。对于计数器这种"近似准确"的场景完全够用,但如果是支付、库存等强一致性场景,需要用 D1 数据库或 R2 对象存储。
六、部署到生产环境
本地测试没问题后,一条命令就能部署到全球边缘节点:
wrangler deploy
部署成功后,Wrangler 会返回一个类似 https://my-first-worker.你的子域名.workers.dev 的默认域名。你可以直接用这个域名访问 API,也可以绑定自己的自定义域名。
6.1 绑定自定义域名
默认的 workers.dev 域名在国内访问偶尔会有波动,建议绑定自己的域名。在 Cloudflare 控制台进入你的 Worker,点击"触发器" → "添加自定义域",输入你的子域名(如 api.zyftools.com)即可。
如果你的域名已经在 Cloudflare 管理,绑定过程是全自动的:Cloudflare 会自动添加 DNS 记录并签发 SSL 证书,不需要你手动操作。
七、与 Cloudflare Pages 集成:Pages Functions
如果你的静态站本身就托管在 Cloudflare Pages 上,还有一个更优雅的方案:Pages Functions。它本质上是 Workers 的"内嵌版",让你把 API 代码直接写在 Pages 项目里,不需要单独维护一个 Worker 项目。
7.1 项目结构
在 Pages 项目的根目录下创建一个 functions 文件夹,Cloudflare 会自动把里面的文件编译成边缘函数。比如:
my-pages-site/
├── index.html # 静态首页
├── about.html
├── functions/ # API 目录
│ ├── api/
│ │ ├── counter.js # 对应 /api/counter
│ │ └── hello.js # 对应 /api/hello
└── wrangler.toml
7.2 编写 Functions 代码
functions/api/counter.js 的内容:
export async function onRequest(context) {
const { request, env } = context;
// 处理 CORS
if (request.method === "OPTIONS") {
return new Response(null, {
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type"
}
});
}
const key = new URL(request.url).searchParams.get("key") || "default";
// 使用 Pages 绑定的 KV
let count = await env.COUNTER_STORE.get(key);
count = count ? parseInt(count) : 0;
count++;
await env.COUNTER_STORE.put(key, count.toString());
return new Response(JSON.stringify({
key: key,
count: count
}), {
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
}
});
}
注意:上述计数器代码在并发访问时可能丢数据(KV 的 get+put 不是原子操作)。对于"近似统计"场景够用,如果需要精确计数,建议使用 Cloudflare D1 数据库或 Workers Analytics Engine。
7.3 绑定 KV 到 Pages 项目
在 Cloudflare 控制台进入你的 Pages 项目,点击"设置" → "函数" → "KV 命名空间绑定",选择之前创建的 COUNTER_STORE,绑定名称填 COUNTER_STORE(和代码里的 env.COUNTER_STORE 对应)。
重新部署 Pages 项目后,访问 https://你的域名/api/counter?key=test 就能看到效果了。
Workers vs Pages Functions 怎么选?如果 API 逻辑简单、和静态站紧密相关(比如表单处理、计数器),用 Pages Functions 更省事,一个项目管所有。如果 API 逻辑复杂、需要被多个站点共用,或者需要自定义路由规则,单独建一个 Worker 项目更灵活。
八、调试与常见问题
实际开发中,我踩过几个坑,这里一并分享出来。
8.1 本地调试技巧
wrangler dev 启动的本地服务器已经能模拟大部分 Workers 环境,但 KV 数据默认是空的。如果你想用真实的 KV 数据做测试,可以在 wrangler.toml 里加上 preview_id,或者在启动命令里指定:
wrangler dev --remote
加上 --remote 后,本地开发环境会直接读写远程的 KV 数据,方便调试。
8.2 CORS 跨域问题
这是新手最容易卡住的地方。如果你的静态站和 API 域名不同(比如静态站在 blog.zyftools.com,API 在 api.zyftools.com),浏览器会触发同源策略限制。解决方案就是在 Worker 响应头里加上 CORS 头,前面示例代码里已经包含了。
如果你用的是 fetch 请求第三方 API 再转发,记得把第三方响应的 CORS 头过滤掉,重新设置自己的:
const response = await fetch("https://第三方API.com/data");
const data = await response.json();
return new Response(JSON.stringify(data), {
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
}
});
8.3 免费额度与限速
Workers 免费版的限制如下:
| 限制项 | 免费版额度 |
|---|---|
| 每日请求数 | 100,000 次 |
| CPU 时间(每次请求) | 10 毫秒 |
| KV 读取(每日) | 100,000 次 |
| KV 写入(每日) | 1,000 次 |
| KV 删除(每日) | 1,000 次 |
对于个人工具站来说,这些额度绰绰有余。我手上流量最大的工具站,日 PV 大概在 3000 左右,Workers 的每日请求数从来没超过 5%。
九、更多实用场景拓展
计数器只是入门,掌握 Workers 后,你可以为静态站实现很多原本需要后端才能做的功能:
- 表单提交处理:接收用户提交的表单数据,转发到 Telegram Bot、Discord Webhook 或自己的邮箱。
- 短链接服务:用 KV 存储短码和长链接的映射,做一个自己的短链系统。
- API 代理与缓存:代理第三方 API 请求,加上响应缓存,既解决跨域问题又降低对方服务器的压力。
- 简单的身份验证:用 JWT 或简单的 Cookie 验证,给部分页面加上访问密码。
- A/B 测试:根据用户 IP 或随机数,返回不同版本的页面内容。
- 请求日志记录:把访问日志写入 KV 或 D1 数据库,做自己的轻量级统计系统。
十、总结
Cloudflare Workers 是我过去一年用过的最顺手的"无服务器"工具。它填补了静态网站和动态需求之间的空白,让个人站长可以在不租服务器、不维护环境的情况下,为站点增加真正有用的后端能力。
对于刚入门的开发者,我的建议是:
- 先跑通 Hello World:确认 Wrangler 安装和登录都没问题。
- 做一个计数器或表单接收:这是最有成就感的第一个实战项目。
- 再考虑 Pages Functions:如果你已经在用 Cloudflare Pages,把 API 代码放到
functions目录里是最省心的方案。 - 不要过度设计:Workers 适合轻量级逻辑,复杂的业务系统还是需要传统后端。
Workers 的学习曲线非常平缓——你会写 JavaScript,就会写 Workers。花一个下午的时间,你的静态站就能拥有真正的 API 能力。
亚飞
评论区功能开发中,如有问题请通过 邮件 联系。