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#

Terminal window
# 安装(推荐 pnpm)
pnpm add -g wrangler
# 或 npm
npm install -g wrangler
# 登录(会打开浏览器授权)
wrangler login
wrangler whoami # 验证登录状态
# 创建新项目
wrangler init my-worker
cd my-worker
# 本地开发(热重载,端口 8787)
wrangler dev
# 部署到生产
wrangler deploy

三、场景一:反向代理#

3.1 通用反向代理#

src/index.js
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,
}));
},
};
Terminal window
# 设置密钥(不进代码仓库)
wrangler secret put OPENAI_API_KEY
# 本地开发用 .dev.vars 文件(加入 .gitignore)
echo "OPENAI_API_KEY=sk-..." > .dev.vars

3.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" });
},
};
Terminal window
# 创建 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 框架:

Terminal window
npm create hono@latest my-api
cd my-api && npm install
src/index.ts
import { 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 });
});
// 文件上传到 R2
app.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 PagesVercelNetlify
免费带宽无限100GB/月100GB/月
免费构建500次/月100次/天300分钟/月
Edge FunctionsWorkers(200+节点)Edge FunctionsEdge Functions
国内访问更好较差较差
自定义域名✅ 免费 SSL✅ 免费 SSL✅ 免费 SSL

6.2 部署 Astro 网站#

Terminal window
# 方式一:Dashboard Git 连接(推荐)
# Cloudflare Dashboard → Pages → Create Project → Connect Git
# Framework: Astro, Build: npm run build, Output: dist
# 方式二:wrangler CLI
npm run build
wrangler pages deploy dist --project-name=my-blog
# 查看部署历史
wrangler pages deployment list --project-name=my-blog

6.3 Pages Functions(边缘 API)#

my-site/
├── public/ # 静态文件
├── src/ # Astro 页面
└── functions/ # 自动部署为 Workers
├── api/
│ └── hello.ts # GET /api/hello
└── _middleware.ts # 全局中间件
functions/api/hello.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 = 8787
local_protocol = "http"
Terminal window
# 常用命令速查
wrangler dev # 本地开发(热重载)
wrangler deploy # 部署到生产
wrangler tail # 实时日志流
wrangler secret put NAME # 设置密钥
wrangler secret list # 查看密钥名称(不显示值)
wrangler kv:namespace list # 查看所有 KV 命名空间
wrangler r2 bucket list # 查看所有 R2 Bucket
wrangler pages deploy dist # 部署静态网站

相关文章

本文基于 wrangler 3.x / Hono 4.x 验证。Cloudflare Workers 平台迭代频繁,以 developers.cloudflare.com 官方文档为准。

Cloudflare Workers 实战完全指南 2026:零成本反代 + Pages 部署 + R2 对象存储
https://971918.xyz/posts/docs/cloudflare-workers-guide/
作者
九所长
发布于
2026-07-31
许可协议
CC BY-NC-SA 4.0