1616 字
8 分钟
Cloudflare Workers 实战完全指南 2026:零成本反代 + Pages 部署 + R2 对象存储
Cloudflare Workers 是运行在 Cloudflare 全球边缘网络(200+ 个数据中心)上的无服务器计算平台,免费套餐每天 10 万次请求——对于个人开发者来说,它能解决大量实际问题:反向代理访问受限的 API、托管静态网站、存储文件,且几乎零成本。
本文从 wrangler CLI 安装开始,完整覆盖 Workers 核心使用场景。
一、免费套餐额度速览
| 资源 | 免费额度 | 付费版($5/月起) |
|---|---|---|
| Workers 请求 | 10万次/天 | 1000亿次/月 |
| CPU 时间 | 10ms/请求 | 30ms/请求 |
| Workers KV 读 | 10万次/天 | 1000亿次/月 |
| Workers KV 写 | 1000次/天 | 10亿次/月 |
| R2 存储 | 10GB | $0.015/GB/月 |
| R2 请求(A类写) | 100万次/月 | 超出按量 |
| R2 请求(B类读) | 1000万次/月 | 超出按量 |
| R2 出口流量 | 永久免费 | 永久免费 |
| Pages 部署次数 | 500次/月 | 无限 |
二、安装 wrangler CLI
# 安装(推荐 pnpm)pnpm add -g wrangler# 或 npmnpm install -g wrangler
# 登录(会打开浏览器授权)wrangler loginwrangler whoami # 验证登录状态
# 创建新项目wrangler init my-workercd my-worker
# 本地开发(热重载,端口 8787)wrangler dev
# 部署到生产wrangler deploy三、场景一:反向代理
3.1 通用反向代理
export default { async fetch(request, env, ctx) { const TARGET_HOST = "api.openai.com"; // 替换为目标域名
const url = new URL(request.url); url.hostname = TARGET_HOST; url.protocol = "https:"; url.port = "";
const newRequest = new Request(url.toString(), { method: request.method, headers: request.headers, body: request.method !== "GET" && request.method !== "HEAD" ? request.body : undefined, redirect: "follow", });
return fetch(newRequest); },};3.2 带鉴权代理(隐藏 API Key)
export default { async fetch(request, env) { // API Key 从 wrangler secret 读取,不出现在代码中 const headers = new Headers(request.headers); headers.set("Authorization", `Bearer ${env.OPENAI_API_KEY}`);
const url = new URL(request.url); url.hostname = "api.openai.com";
// 只允许特定路径 const allowedPaths = ["/v1/chat/completions", "/v1/models"]; if (!allowedPaths.some(p => url.pathname.startsWith(p))) { return new Response("Not Found", { status: 404 }); }
return fetch(new Request(url.toString(), { method: request.method, headers: headers, body: request.body, })); },};# 设置密钥(不进代码仓库)wrangler secret put OPENAI_API_KEY
# 本地开发用 .dev.vars 文件(加入 .gitignore)echo "OPENAI_API_KEY=sk-..." > .dev.vars3.3 CORS 代理
export default { async fetch(request) { const CORS_HEADERS = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS", "Access-Control-Allow-Headers": "Content-Type, Authorization", };
// 处理 OPTIONS 预检请求 if (request.method === "OPTIONS") { return new Response(null, { status: 204, headers: CORS_HEADERS }); }
const url = new URL(request.url); url.hostname = "api.example.com";
const response = await fetch(new Request(url.toString(), request));
const newHeaders = new Headers(response.headers); for (const [k, v] of Object.entries(CORS_HEADERS)) newHeaders.set(k, v);
return new Response(response.body, { status: response.status, headers: newHeaders }); },};四、场景二:Workers KV 键值缓存
// wrangler.toml 需要绑定:// [[kv_namespaces]]// binding = "MY_KV"// id = "your-namespace-id"
export default { async fetch(request, env) { const url = new URL(request.url); const key = url.searchParams.get("key") ?? "default";
// 尝试读缓存 const cached = await env.MY_KV.get(key, { type: "json" }); if (cached) { return Response.json({ data: cached, cache: "HIT" }); }
// 缓存未命中,请求上游 const data = await fetch(`https://api.example.com/data/${key}`) .then(r => r.json());
// 写入缓存,TTL 3600 秒 await env.MY_KV.put(key, JSON.stringify(data), { expirationTtl: 3600 });
return Response.json({ data, cache: "MISS" }); },};# 创建 KV 命名空间wrangler kv:namespace create MY_KV
# 命令行读写wrangler kv:key put --namespace-id=<id> "mykey" "myvalue"wrangler kv:key get --namespace-id=<id> "mykey"wrangler kv:key list --namespace-id=<id>wrangler kv:key delete --namespace-id=<id> "mykey"五、场景三:用 Hono 构建 API
Hono 是专为边缘运行时设计的轻量 Web 框架:
npm create hono@latest my-apicd my-api && npm installimport { Hono } from "hono";import { cors } from "hono/cors";import { logger } from "hono/logger";import { jwt } from "hono/jwt";
type Bindings = { MY_KV: KVNamespace; MY_R2: R2Bucket; JWT_SECRET: string;};
const app = new Hono<{ Bindings: Bindings }>();
app.use("*", logger());app.use("/api/*", cors());
// 公开路由app.get("/", c => c.json({ message: "Hello from Hono on Workers!" }));app.get("/api/health", c => c.json({ status: "ok", ts: Date.now() }));
// JWT 鉴权路由app.use("/api/protected/*", jwt({ secret: c => c.env.JWT_SECRET }));
app.get("/api/protected/data", async c => { const payload = c.get("jwtPayload"); const data = await c.env.MY_KV.get(`user:${payload.sub}`, { type: "json" }); return c.json({ user: payload.sub, data });});
// 文件上传到 R2app.post("/api/upload", async c => { const form = await c.req.formData(); const file = form.get("file") as File; if (!file) return c.json({ error: "No file" }, 400);
const key = `uploads/${Date.now()}-${file.name}`; await c.env.MY_R2.put(key, file.stream(), { httpMetadata: { contentType: file.type }, }); return c.json({ key }, 201);});
export default app;六、场景四:Cloudflare Pages 静态部署
6.1 Pages vs Vercel vs Netlify
| 特性 | Cloudflare Pages | Vercel | Netlify |
|---|---|---|---|
| 免费带宽 | 无限 | 100GB/月 | 100GB/月 |
| 免费构建 | 500次/月 | 100次/天 | 300分钟/月 |
| Edge Functions | Workers(200+节点) | Edge Functions | Edge Functions |
| 国内访问 | 更好 | 较差 | 较差 |
| 自定义域名 | ✅ 免费 SSL | ✅ 免费 SSL | ✅ 免费 SSL |
6.2 部署 Astro 网站
# 方式一:Dashboard Git 连接(推荐)# Cloudflare Dashboard → Pages → Create Project → Connect Git# Framework: Astro, Build: npm run build, Output: dist
# 方式二:wrangler CLInpm run buildwrangler pages deploy dist --project-name=my-blog
# 查看部署历史wrangler pages deployment list --project-name=my-blog6.3 Pages Functions(边缘 API)
my-site/├── public/ # 静态文件├── src/ # Astro 页面└── functions/ # 自动部署为 Workers ├── api/ │ └── hello.ts # GET /api/hello └── _middleware.ts # 全局中间件export const onRequest: PagesFunction = async (context) => { return Response.json({ message: "Hello from Pages Function!", country: context.request.cf?.country, city: context.request.cf?.city, });};七、场景五:R2 对象存储
7.1 Workers 操作 R2
// wrangler.toml:// [[r2_buckets]]// binding = "MY_BUCKET"// bucket_name = "my-bucket"
export default { async fetch(request, env) { const key = new URL(request.url).pathname.slice(1);
switch (request.method) { case "GET": { const obj = await env.MY_BUCKET.get(key); if (!obj) return new Response("Not Found", { status: 404 });
const headers = new Headers(); obj.writeHttpMetadata(headers); headers.set("etag", obj.httpEtag); headers.set("Cache-Control", "public, max-age=31536000"); return new Response(obj.body, { headers }); }
case "PUT": { const ct = request.headers.get("Content-Type") ?? "application/octet-stream"; await env.MY_BUCKET.put(key, request.body, { httpMetadata: { contentType: ct }, }); return new Response(`OK: ${key}`, { status: 201 }); }
case "DELETE": { await env.MY_BUCKET.delete(key); return new Response("Deleted"); }
default: return new Response("Method Not Allowed", { status: 405 }); } },};7.2 S3 SDK 访问 R2(兼容接口)
import { S3Client, PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";
// 只需替换 endpoint,其余与 S3 完全一样const r2 = new S3Client({ region: "auto", endpoint: `https://${process.env.CF_ACCOUNT_ID}.r2.cloudflarestorage.com`, credentials: { accessKeyId: process.env.R2_ACCESS_KEY_ID!, secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!, },});
// 上传await r2.send(new PutObjectCommand({ Bucket: "my-bucket", Key: "images/avatar.png", Body: fileBuffer, ContentType: "image/png",}));八、wrangler.toml 完整参考
name = "my-worker"main = "src/index.ts"compatibility_date = "2024-09-23"compatibility_flags = ["nodejs_compat"] # 支持 Node.js API 子集
[[kv_namespaces]]binding = "MY_KV"id = "your-kv-namespace-id"preview_id = "your-preview-kv-id"
[[r2_buckets]]binding = "MY_BUCKET"bucket_name = "my-bucket"
# 非敏感环境变量[vars]API_BASE_URL = "https://api.example.com"ENVIRONMENT = "production"# 敏感变量用 wrangler secret put 设置,不放这里!
# 自定义域名[[routes]]pattern = "api.example.com/*"zone_name = "example.com"
[dev]port = 8787local_protocol = "http"# 常用命令速查wrangler dev # 本地开发(热重载)wrangler deploy # 部署到生产wrangler tail # 实时日志流wrangler secret put NAME # 设置密钥wrangler secret list # 查看密钥名称(不显示值)wrangler kv:namespace list # 查看所有 KV 命名空间wrangler r2 bucket list # 查看所有 R2 Bucketwrangler pages deploy dist # 部署静态网站相关文章:
- Nginx 进阶完全指南 2026:反向代理 + HTTPS + 负载均衡
- GitHub 打不开/访问慢?2026年最新解决方法
- Linux 服务器初始化安全配置:买完 VPS 必做的 12 件事
- Docker 完全指南 2026:Compose 多服务编排与生产部署
- FastAPI 完全指南 2026:从零构建高性能异步 Python API
本文基于 wrangler 3.x / Hono 4.x 验证。Cloudflare Workers 平台迭代频繁,以 developers.cloudflare.com 官方文档为准。
Cloudflare Workers 实战完全指南 2026:零成本反代 + Pages 部署 + R2 对象存储
https://971918.xyz/posts/docs/cloudflare-workers-guide/