Cloudflare Workers 全栈应用：正确使用 Cache API 加速网站

在使用 Cloudflare Workers 构建全栈应用时，很多开发者会遇到一个误区：以为直接在 Worker 的 Response 中设置 HTTP 缓存头（如 Cache-Control），就能自动触发 CDN 缓存。事实并非如此。如果只设置响应头，请求依然会穿透 CDN 到达你的 Worker，导致 cf-cache-status 无法出现。这意味着每次请求，Worker 都要完整执行一遍业务逻辑（如 SSR 渲染、数据库查询等），这将大量消耗计算时长（CPU Time/Duration）并增加用户等待时间。要想真正利用 Cloudflare 的边缘节点缓存，避免重复执行繁重的渲染任务，必须在 Worker 内部显式使用 Cache API。 1. 正确姿势：使用 Cache API 我们需要在 Worker 内部手动拦截请求，先去 caches.default 查询。如果未命中，再执行回源逻辑，并将结果写入缓存。以下是一个标准的 TypeScript 实现模板： interface Env {} export default { async fetch(request, env, ctx): Promise { const cacheUrl = new URL(request.url); // 1. 构建 Cache Key // 注意：通常使用 request 对象或 url 字符串作为 key const cacheKey = new Request(cacheUrl.toString(), request); const cache = caches.default; // 2. 检查是否命中缓存 let response = await cache.match(cacheKey); if (!response) { console.log( `[Cache Miss] ${request.url}. Fetching and caching request.` ); // 3. 回源获取数据 (这里可以是 upstream fetch，也可以是数据库查询结果的组装) response = await fetch(request); // 4. 构造新的响应用于缓存 // 必须重新构造 Response，因为原本的 response body 流只能读取一次 response = new Response(response.body, response); // 5. 设置缓存头 // s-maxage 控制 CDN 缓存时间 response.headers.append("Cache-Control", "s-maxage=10"); // 6. 写入缓存 // 使用 ctx.waitUntil 确保返回响应给用户后，写入缓存的操作不会被杀掉 ctx.waitUntil(cache.put(cacheKey, response.clone())); } else { console.log(`[Cache Hit] ${request.url}.`); } return response; }, } satisfies ExportedHandler; 2. 进阶策略：配合 Purge API 实现“激进缓存” 一旦掌握了 Cache API，你就可以采用更激进的缓存策略（例如设置很长的 s-maxage），然后通过编程式刷新（Purge）来保证内容的实时性。 Cloudflare 提供了强大的 Purge API，支持按精确 URL或前缀（Prefix）清除缓存。你需要先在 Dashboard 获取一个拥有 Zone.Cache:Purge 权限的 Token。 const purgeCache = async () => { const response = await fetch( `https://api.cloudflare.com/client/v4/zones/${CLOUDFLARE_ZONE_ID}/purge_cache`, { method: "POST", headers: { "Authorization": `Bearer ${CLOUDFLARE_PURGE_API_TOKEN}`, "Content-Type": "application/json", }, // 注意：body 需要序列化为字符串 body: JSON.stringify({ files: ["https://example.com/about"], // 精确清除 prefixes: ["https://example.com/posts"], // 按前缀清除（清除该路径下所有资源） }), }, ); return response.json(); }; 这样就可以做到及时更新页面