关于 cloudflare-workers
面向构建和部署边缘端 JavaScript 与 TypeScript 函数的技能,涵盖 API、中间件、定时任务及存储绑定的开发与配置。
主要功能
- 01部署边缘端函数
- 02构建 API 和微服务
- 03配置中间件与路由
- 04使用 KV、D1 和 R2 绑定
- 05设置 Cron 触发器
适用场景
- 01构建轻量级边缘 API
- 02在源站前添加限流中间件
- 03按计划运行后台任务
- 04处理 Webhook 或图像转换
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ bagelhole/ devops-security-agent-skills --skill cloudflare-workers安装后在 Claude Code 中输入/cloudflare-workers确认已加载。
详细介绍
Cloudflare Workers
将 JavaScript 和 TypeScript 函数部署到 Cloudflare 的全球边缘网络,实现亚毫秒级冷启动。
适用场景
- 在边缘构建轻量级 API 和微服务。
- 在源服务器前添加中间件(身份验证、速率限制、注入标头)。
- 按计划运行 Cron 作业,无需维护基础设施。
- 处理 Webhook、图像转换或 A/B 测试逻辑。
- 通过 KV、D1 或 R2 存储绑定提供动态内容。
前提条件
- 本地已安装 Node.js 18+。
- Wrangler CLI:
npm install -g wrangler。 - Cloudflare 账户(免费套餐支持每天 100,000 个请求)。
- 已完成身份验证:运行
wrangler login或设置CLOUDFLARE_API_TOKEN。
快速入门
# Scaffold a new Worker project
npm create cloudflare@latest my-worker
cd my-worker
# Login to Cloudflare
npx wrangler login
# Start local development server (port 8787)
npx wrangler dev
# Deploy to production
npx wrangler deploy
Wrangler 必备命令
# Local development with remote bindings (KV, D1, R2)
npx wrangler dev --remote
# Deploy to a specific environment
npx wrangler deploy --env staging
# Set a secret (prompts for value)
npx wrangler secret put API_TOKEN
npx wrangler secret put API_TOKEN --env staging
# List secrets
npx wrangler secret list
# Tail production logs in real time
npx wrangler tail
# Tail with filters
npx wrangler tail --status=error --search="timeout"
# View deployment versions
npx wrangler deployments list
# Rollback to a previous deployment
npx wrangler rollback
Wrangler 配置
# wrangler.toml
name = "my-api"
main = "src/index.ts"
compatibility_date = "2024-09-01"
compatibility_flags = ["nodejs_compat"]
# Custom routes
routes = [
{ pattern = "api.example.com/*", zone_name = "example.com" }
]
# Or use a workers.dev subdomain
# workers_dev = true
# Environment variables (non-secret)
[vars]
ENVIRONMENT = "production"
API_VERSION = "v2"
# Staging environment override
[env.staging]
name = "my-api-staging"
routes = [
{ pattern = "api-staging.example.com/*", zone_name = "example.com" }
]
[env.staging.vars]
ENVIRONMENT = "staging"
Worker 示例
基本 API 路由器
// src/index.ts
export interface Env {
ENVIRONMENT: string;
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
switch (url.pathname) {
case "/":
return new Response("OK", { status: 200 });
case "/api/health":
return Response.json({
status: "healthy",
env: env.ENVIRONMENT,
timestamp: new Date().toISOString(),
});
case "/api/data":
if (request.method !== "POST") {
return new Response("Method Not Allowed", { status: 405 });
}
const body = await request.json();
// Process in the background after returning response
ctx.waitUntil(logToAnalytics(body));
return Response.json({ received: true });
default:
return new Response("Not Found", { status: 404 });
}
},
};
async function logToAnalytics(data: unknown): Promise<void> {
await fetch("https://analytics.example.com/ingest", {
method: "POST",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" },
});
}
中间件:使用 KV 实现速率限制
// src/rate-limiter.ts
interface Env {
RATE_LIMIT_KV: KVNamespace;
ORIGIN_URL: string;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const ip = request.headers.get("CF-Connecting-IP") || "unknown";
const key = `ratelimit:${ip}`;
const window = 60; // seconds
const maxRequests = 100;
const current = parseInt((await env.RATE_LIMIT_KV.get(key)) || "0");
if (current >= maxRequests) {
return new Response("Too Many Requests", {
status: 429,
headers: { "Retry-After": String(window) },
});
}
await env.RATE_LIMIT_KV.put(key, String(current + 1), {
expirationTtl: window,
});
// Forward to origin
const originRequest = new Request(env.ORIGIN_URL + new URL(request.url).pathname, request);
return fetch(originRequest);
},
};
KV 存储绑定
# wrangler.toml
[[kv_namespaces]]
binding = "MY_KV"
id = "abc123def456"
# Preview namespace for local dev
[[kv_namespaces]]
binding = "MY_KV"
id = "abc123def456"
preview_id = "preview789"
// KV operations in a Worker
interface Env {
MY_KV: KVNamespace;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// Write with TTL
await env.MY_KV.put("session:abc", JSON.stringify({ user: "alice" }), {
expirationTtl: 3600,
});
// Read
const session = await env.MY_KV.get("session:abc", "json");
// List keys by prefix
const list = await env.MY_KV.list({ prefix: "session:", limit: 100 });
// Delete
await env.MY_KV.delete("session:abc");
return Response.json({ session, keys: list.keys.length });
},
};
# KV CLI operations
npx wrangler kv namespace create MY_KV
npx wrangler kv namespace list
npx wrangler kv key put --namespace-id=abc123 "config:feature-flags" '{"darkMode":true}'
npx wrangler kv key get --namespace-id=abc123 "config:feature-flags"
npx wrangler kv key list --namespace-id=abc123 --prefix="config:"
D1 数据库绑定
# wrangler.toml
[[d1_databases]]
binding = "DB"
database_name = "my-app"
database_id = "xxxx-yyyy-zzzz"
// D1 SQL queries in a Worker
interface Env {
DB: D1Database;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// Parameterized query
const { results } = await env.DB.prepare(
"SELECT id, name, email FROM users WHERE active = ? LIMIT ?"
)
.bind(1, 50)
.all();
// Insert
await env.DB.prepare("INSERT INTO users (name, email) VALUES (?, ?)")
.bind("Alice", "[email protected]")
.run();
// Batch multiple statements
await env.DB.batch([
env.DB.prepare("UPDATE users SET active = 0 WHERE last_login < ?").bind("2024-01-01"),
env.DB.prepare("DELETE FROM sessions WHERE expires_at < ?").bind(Date.now()),
]);
return Response.json(results);
},
};
# D1 CLI operations
npx wrangler d1 create my-app
npx wrangler d1 list
npx wrangler d1 execute my-app --command="CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, active INTEGER DEFAULT 1)"
npx wrangler d1 execute my-app --file=./migrations/001_init.sql
npx wrangler d1 execute my-app --command="SELECT * FROM users" --json
Cron 触发器
# wrangler.toml
[triggers]
crons = [
"0 */6 * * *", # Every 6 hours
"0 0 * * MON", # Every Monday at midnight
"*/15 * * * *", # Every 15 minutes
]
// src/index.ts — scheduled handler
export default {
async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext): Promise<void> {
switch (event.cron) {
case "0 */6 * * *":
ctx.waitUntil(cleanupExpiredSessions(env));
break;
case "0 0 * * MON":
ctx.waitUntil(generateWeeklyReport(env));
break;
}
},
async fetch(request: Request, env: Env): Promise<Response> {
return new Response("OK");
},
};
Durable Objects
# wrangler.toml
[durable_objects]
bindings = [
{ name = "COUNTER", class_name = "Counter" }
]
[[migrations]]
tag = "v1"
new_classes = ["Counter"]
// src/counter.ts — Durable Object class
export class Counter {
state: DurableObjectState;
constructor(state: DurableObjectState) {
this.state = state;
}
async fetch(request: Request): Promise<Response> {
let count = (await this.state.storage.get<number>("count")) || 0;
count++;
await this.state.storage.put("count", count);
return Response.json({ count });
}
}
// src/index.ts — route to Durable Object
interface Env {
COUNTER: DurableObjectNamespace;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const id = env.COUNTER.idFromName("global-counter");
const stub = env.COUNTER.get(id);
return stub.fetch(request);
},
};
自定义路由
# Route to specific zones
routes = [
{ pattern = "api.example.com/v1/*", zone_name = "example.com" },
{ pattern = "api.example.com/v2/*", zone_name = "example.com" },
]
# Or use custom domains (automatic SSL)
# Dashboard: Workers > your-worker > Triggers > Custom Domains
故障排除
| 症状 | 原因 | 修复方法 |
|---|---|---|
Error 1101: Worker threw exception | fetch 处理程序中存在未处理的错误 | 使用 try/catch 包装处理程序;通过 wrangler tail 查看堆栈跟踪 |
exceeded CPU time limit | Worker 超出 10ms(免费套餐)或 30s(付费套餐)的 CPU 时间限制 | 优化代码;使用 ctx.waitUntil() 将工作移至后台 |
| KV 读取返回过期数据 | KV 最终一致(约 60s) | 使用 cacheTtl 选项,或切换到 Durable Objects 以实现强一致性 |
wrangler dev 绑定错误 | 未配置本地绑定 | 使用 --remote 标志,或在 wrangler.toml 中配置 preview_id |
| Worker 中找不到 Secret | Secret 为错误的环境设置 | 使用 wrangler secret list --env <env> 验证 |
| 浏览器报告 CORS 错误 | 响应中缺少 CORS 标头 | 添加 Access-Control-Allow-Origin 标头;处理 OPTIONS 预检请求 |
| 路由不匹配 | 模式不包含 /* 后缀 | 添加 /* 以匹配所有路径:api.example.com/* |
相关技能
- cloudflare-pages - 使用 Pages Functions 部署前端
- cloudflare-r2 - 边缘对象存储
- cloudflare-zero-trust - 使用 Access 保护 Worker 端点
评论
支持 Markdown