Cloudflare Workers Playground 常用模式实战:从 JSON API 到缓存与认证的 8 大代码范式
【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills
本篇技术指南以 Skills Catalog for Codex 仓库中 patterns.md 为骨架,系统讲解在 Cloudflare Workers Playground 中开发边缘逻辑的 8 种核心代码模式(JSON API、路由、反向代理、CORS、缓存、框架集成、认证、错误处理)。读完本文,你将掌握无需任何账号与本地环境即可在浏览器沙箱中编写、测试并一键部署真实 Workers 代码的完整实战方案,同时理解其底层运行时约束。
Workers Playground 是什么
Cloudflare Workers Playground 是官方提供的浏览器端 Workers 沙箱,用于在无需认证、无需本地搭建的情况下即时实验、测试甚至部署 Cloudflare Workers。根据仓库中 workers-playground/README.md 的说明,它具备三个核心能力:
- 零配置启动:打开网页即可写代码,无 CLI、无账号、无配置文件,代码运行在真实的 Cloudflare Workers 运行时(V8 isolates)上;
- 即时预览:代码修改自动重载,内置浏览器标签页与 HTTP 测试面板,支持右键 Inspect 打开 DevTools;
- 分享与部署:Copy Link 生成永久分享链接(代码内嵌于 URL fragment,永不过期),Deploy 按钮约 30 秒内发布到生产环境并立即获得
*.workers.dev子域名。
Playground 的硬性约束(先看再写)
patterns.md 中的每个示例都基于以下约束设计,理解它们才能写出可运行的代码。下表整理自 workers-playground/configuration.md 与 workers-playground/README.md:
| 约束 | Playground | 生产 Workers(wrangler) |
|---|---|---|
| 模块格式 | 仅 ES modules(export default) | ES modules 或 Service Worker |
| TypeScript | 不支持(仅纯 JavaScript) | 支持(构建步骤) |
| Bindings(KV/D1/R2/Durable Objects) | 不可用,env恒为{} | 完整支持 |
| 环境变量 / Secrets | 不可用 | 完整支持 |
| wrangler.toml | 不使用 | 必需 |
| 自定义域名 | 不可用 | 完整支持 |
| 浏览器兼容 | Chrome/Firefox/Edge 正常;Safari 预览报PreviewRequestFailed | — |
因此,Playground 只适合快速原型验证。部署到生产环境请改用wranglerCLI(参见 workers/README.md 中的npx wrangler dev/npx wrangler deploy工作流)。所有示例的入口都是导出默认对象的fetch处理器,签名固定为async fetch(request, env, ctx),且必须返回Response对象。
模式一:JSON API(Response.json 快速返回结构化数据)
JSON API 是最基础的模式,用于快速搭建只读接口或 echo 服务:
export default { async fetch(request) { const url = new URL(request.url); if (url.pathname === '/api/hello') return Response.json({ message: 'Hello' }); if (url.pathname === '/api/echo' && request.method === 'POST') { return Response.json({ received: await request.json() }); } return Response.json({ error: 'Not found' }, { status: 404 }); } };要点拆解:
Response.json(data, init)是 Workers 运行时提供的便捷构造器,自动设置Content-Type: application/json,第二个参数可传入{ status, headers };new URL(request.url)用于解析路径与查询参数。结合 workers-playground/api.md,url.searchParams.get('page')取单值、url.searchParams.getAll('tag')取数组;- 使用
request.json()读取请求体时,body 流会被消费。若后续还需要请求体,务必先request.clone()(详见错误处理一节); - 404 兜底返回保证了接口的规范性。
模式二:Router Pattern(零依赖路径路由)
不引入框架时,可以用一个普通对象实现路径到处理函数的映射:
const routes = { '/': () => new Response('Home'), '/api/users': () => Response.json([{ id: 1, name: 'Alice' }]) }; export default { async fetch(request) { const handler = routes[new URL(request.url).pathname]; return handler ? handler() : new Response('Not Found', { status: 404 }); } };这个模式将"路由表"与"处理逻辑"解耦,扩展新端点只需在routes对象中增加键值对。从源码结构看,它本质上是一种查表式(lookup-table)分发,无需任何第三方依赖,适合 Playground 中的快速原型。
生产环境的 Workers 参考文档 workers/patterns.md 给出了更完整的变体:把 HTTP 方法也纳入路由键,形如const router = { 'GET /api/users': handleGetUsers, 'POST /api/users': handleCreateUser },再通过router[\${request.method} ${url.pathname}`]` 查找。若路由进一步复杂,可引入 Hono、itty-router 或 Worktop。
模式三:Proxy Pattern(边缘反向代理)
代理模式把请求原样转发到上游服务,常用于网关、灰度或安全过滤:
export default { async fetch(request) { const url = new URL(request.url); url.hostname = 'api.example.com'; return fetch(url.toString(), { method: request.method, headers: request.headers, body: request.body }); } };实现原理:fetch是 Workers 运行时内置的 Web 标准 API(workers-playground/api.md 中有fetch(url, { method, headers, body })的完整签名)。这里仅改写url.hostname后透传方法与头,即完成整站反向代理——这正是 Workers "请求/响应变换"核心用法的体现(workers/README.md 将 Proxy/routing logic 列为 Workers 的典型适用场景)。
注意:如果之前已读取过request.body(例如用于校验),透传request.body会因流已被消费而报 "Response body already read" 错误,此时应传入request.clone().body。
模式四:CORS Handling(跨域请求处理)
Workers 部署在独立域名(如xxx.workers.dev)上,浏览器跨域调用必须处理 CORS。标准做法是先应答预检(preflight),再在响应上注入 CORS 头:
export default { async fetch(request) { if (request.method === 'OPTIONS') { return new Response(null, { headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE', 'Access-Control-Allow-Headers': 'Content-Type, Authorization' } }); } const response = await fetch('https://api.example.com', request); const modified = new Response(response.body, response); modified.headers.set('Access-Control-Allow-Origin', '*'); return modified; } };要点拆解:
OPTIONS预检请求不带业务 body,直接返回 204 语义的空Response,并声明允许的来源、方法与请求头;- 对真实响应,通过
new Response(response.body, response)复制原响应的 body 与状态,再追加 CORS 头——这种"包装式修改"比直接改response.headers更可控,也是 workers-playground/api.md 中 "Modify existing response" 的推荐写法; - 生产环境可参考 workers/patterns.md 将 CORS 头提取为常量
corsHeaders复用。
模式五:Caching(基于 caches.default 的边缘缓存)
Workers 运行时提供全局caches.default,可对GET请求实现"先查缓存、未命中回源、命中即写"的标准流程:
export default { async fetch(request) { if (request.method !== 'GET') return fetch(request); const cache = caches.default; let response = await cache.match(request); if (!response) { response = await fetch('https://api.example.com'); if (response.status === 200) await cache.put(request, response.clone()); } return response; } };要点拆解:
- 非
GET请求直接透传,避免把 POST 等副作用请求错误地写入缓存; cache.put(request, response.clone())中clone()是必须的:Response的 body 是单次可读流,直接 put 后再return response会因 body 已被消费而报错。这一点在 workers-playground/api.md 的 Cache 一节有明确注释 "Clone before put!";cache.match(request)使用请求的 URL 与方法作为缓存键;如需自定义缓存策略,可构造新的Request(url, { method: 'GET' })作为键。
模式六:Hono Framework(从 CDN 导入框架)
Playground 不支持本地npm install,但支持从 CDN 导入模块,因此可以无缝使用 Hono 等框架:
import { Hono } from 'https://esm.sh/hono@3'; const app = new Hono(); app.get('/', (c) => c.text('Hello')); app.get('/api/users/:id', (c) => c.json({ id: c.req.param('id') })); app.notFound((c) => c.json({ error: 'Not found' }, 404)); export default app;要点拆解:
import { Hono } from 'https://esm.sh/hono@3'走的是 esm.sh CDN,版本号显式锁定在 v3,保证可复现;- 注意 Hono 的
app本身就是合法的 Workersfetch处理器(满足export default对象协议),可以直接导出; c.req.param('id')提供路径参数,app.notFound统一兜底 404;- 同样的思路也适用于 itty-router 等其他纯 ESM 框架(workers-playground/README.md 将 "Framework testing: Import from CDN" 列为典型用例)。若要在 Playground 里以经典写法使用 Hono,可参照其 README 中的变体:在
fetch内return app.fetch(request)。
模式七:Authentication(Bearer Token 认证)
在 Worker 入口统一校验Authorization头,是构建受保护 API 的最简方式:
export default { async fetch(request) { const auth = request.headers.get('Authorization'); if (!auth?.startsWith('Bearer ')) { return Response.json({ error: 'Unauthorized' }, { status: 401 }); } const token = auth.substring(7); if (token !== 'secret-token') { return Response.json({ error: 'Invalid token' }, { status: 403 }); } return Response.json({ message: 'Authenticated' }); } };要点拆解:
- 两级错误语义:缺失/格式错误返回 401(未认证),token 值不匹配返回 403(无权限);
auth.substring(7)去掉"Bearer "前缀(6 个字符加 1 个空格);- 安全提醒:Playground 没有 Secrets 机制(workers-playground/gotchas.md 明确说明 "No env vars → hardcode for testing"),示例中的
'secret-token'硬编码仅供本地原型验证。生产环境必须使用npx wrangler secret put API_KEY存入密钥,再通过env.API_KEY读取(参见 workers/configuration.md),绝不可把真实凭据写死在代码里。
模式八:Error Handling(统一异常兜底)
Worker 入口用 try/catch 包住核心逻辑,将上游失败转换为结构化 JSON 错误响应:
export default { async fetch(request) { try { const response = await fetch('https://api.example.com'); if (!response.ok) throw new Error(`API returned ${response.status}`); return response; } catch (error) { return Response.json({ error: error.message }, { status: 500 }); } } };要点拆解:
!response.ok覆盖所有 4xx/5xx 状态码,把上游错误显式转为异常;- catch 统一返回 500 + 错误信息 JSON,避免抛出未处理异常导致连接被重置;
- 生产级的增强做法见 workers/patterns.md:自定义
HTTPError类携带 status,按错误类型分别返回 4xx 业务错误与 500 兜底,并结合ctx.waitUntil做后台日志上报。
常见运行时错误与规避(Gotchas 速查)
基于 workers-playground/gotchas.md 的实践,以下是 Playground 中最容易踩的坑:
| 错误 | 根因 | 规避方案 |
|---|---|---|
| "Response body already read" | body 流被消费两次 | 先request.clone()再分别读取 |
| "Worker exceeded CPU time" | 单请求 CPU 超过 10ms(免费)/ 50ms(付费) | 用ctx.waitUntil()把慢操作移到后台 |
| "Too many subrequests" | 超过 50 次(免费)/ 1000 次(付费)出站 fetch | 合并为批量 API 调用 |
| PreviewRequestFailed(Safari) | 浏览器不兼容 | 改用 Chrome/Firefox/Edge |
正确与错误的 body 复用对比:
// ❌ body 被消费两次 const body = await request.text(); await fetch(url, { body: request.body }); // Error! // ✅ 先克隆再读取 const clone = request.clone(); const body = await request.text(); await fetch(url, { body: clone.body });状态持久化的边界:为什么内存状态不可靠
patterns.md 在末尾有一条关键注意事项:内存状态(Map、变量)在 Worker 冷启动时会重置。这是因为 Workers 运行在 V8 isolates 上,每次冷启动都会重建隔离环境(workers/README.md 指出其冷启动虽然极快,但每个 isolate 生命周期内的内存并不跨请求保证持久)。因此:
- Playground 中任何用全局变量累计的计数器、会话等都会在冷启动后归零,只适合演示;
- 需要持久化时,生产环境应使用 Durable Objects(强一致、按实体保持状态)或 KV(键值存储)——这正是 SKILL.md 决策树中 "存储" 分支的指引:key-value →
kv/,强一致按实体状态 →durable-objects/; - Playground 本身不提供任何 binding,原型阶段如需状态,可用外部 API 或在前端维护。
从 Playground 到生产:部署与差距对照
Playground 的Deploy按钮可将当前代码一键发布:登录 Cloudflare 账号(无账号会自动创建)→ 确认 Worker 名称与代码 → 约 30 秒部署到全球网络 → 获得<name>.workers.dev子域名 → 在 Dashboard 中继续添加 bindings、自定义域名与监控。
但必须清醒认识 Playground 与生产环境的差距(workers-playground/configuration.md 的 Limits 一节):
| 资源 | Playground / 免费额度 | 付费额度 |
|---|---|---|
| CPU 时间 | 10ms / 请求 | 50ms / 请求 |
| 内存 | 128 MB | 128 MB |
| 脚本大小 | 1 MB(压缩后) | — |
| 子请求数 | 50 | 1000 |
| 请求体大小 | 100 MB(入站) | — |
推荐路径:Playground 完成原型验证后,用wrangler建立正式工程——npm create cloudflare@latest脚手架 +npx wrangler dev本地调试 +npx wrangler deploy发布(workers/README.md)。部署前可用npx wrangler whoami确认认证状态(SKILL.md)。届时即可在 wrangler.jsonc 配置 中声明 KV、D1、R2、Durable Objects 等 bindings,将 Playground 中无法验证的持久化逻辑补全。
小结
本文覆盖了 Workers Playground 中最常用的 8 个代码模式,它们共同构成了边缘逻辑开发的最小技能集:JSON API 处理数据出入、Router 组织路由、Proxy 转发流量、CORS 打通跨域、Caching 提升性能、Hono 加速框架化开发、Authentication 守护接口、Error Handling 保证健壮性。所有示例均可直接粘贴到 Playground 运行验证。进阶读者可继续阅读同目录下的 workers-playground/api.md(Request/Response/ExecutionContext/Cache/Crypto 全套 API 速查)、workers-playground/configuration.md(部署与限制)与 workers-playground/gotchas.md(排错清单),并在迁移生产时对照 workers/patterns.md 补齐 TypeScript、测试与监控能力。
【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考