Cloudflare Pages 部署排障全指南:Gotchas 疑难清单与实战排查手册
【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills
本指南以 Cloudflare Deploy 技能仓库中 Cloudflare Pages 排障清单 为骨架,系统梳理 Pages 与 Pages Functions 部署、运行时最常踩的坑:从 Functions 404、静态资源失效、Bindings 不生效,到中间件、
_headers/_redirects、类型错误、本地开发、性能、Smart Placement 与远程绑定问题,并给出可复制的修复命令与源码级佐证。读完你将获得一张可直接对照执行的"排障决策表",并能结合 configuration.md 与 api.md 快速定位问题根因。
一、排障思路:症状 → 原因 → 解决
Pages 项目的绝大多数故障都集中在四类根因:构建输出与配置不匹配、路由文件(_routes.json)误配、绑定(Bindings)未对齐、框架适配器状态不明。仓库中的 gotchas.md 正是按"症状—原因—解决"三段式组织,本文沿此脉络逐项展开,并补充底层配置与源码佐证。
二、Functions 不执行:端点 404 或方法不触发
症状:Function 端点返回 404,或请求根本没进入函数代码。
常见原因(三选一或叠加出现):
_routes.json把目标路径写进了exclude,导致请求被当作静态资源处理;- 函数文件扩展名错误(如写成
.jsx/.tsx),Pages Functions 只识别.js/.ts; - Functions 目录没有位于构建输出根目录(
pages_build_output_dir)之下。
解决步骤:
- 检查 _routes.json(默认位于构建输出目录内),确认目标路径未被
exclude命中。注意exclude优先级高于include,且 Functions 是按计量计费的,把静态资源排除在外同时是省钱手段; - 将函数文件重命名为
.ts/.js后缀; - 核对
wrangler.jsonc中的pages_build_output_dir(如./dist),确认/functions目录位于该输出目录内。
从 文件路由规则 看,/functions/api/users.ts会映射为/api/users,[id].ts对应:id单段参数,[[path]].ts对应多段 catchall——文件位置即路由,目录层级错位必然导致 404。
三、静态资源 404:文件无法访问
症状:CSS/JS/图片等静态文件返回 404。
常见原因:
- 构建输出目录配置错误,产物没落到正确位置;
- Functions 抢占了静态请求(路由过宽,把静态路径也纳入了函数处理);
- 使用 Advanced Mode(
_worker.js)时,代码里缺少env.ASSETS.fetch()回退逻辑。
解决步骤:
- 核对 Dashboard 构建设置或
wrangler.jsonc中的输出目录,确认dist产物完整; - 在 _routes.json 的
exclude中加入静态资源模式,例如"/build/*"、"/static/*"、"/*.{ico,png,jpg,css,js}"; - 若使用 Advanced Mode,必须在
_worker.js中调用env.ASSETS.fetch(request)兜底静态资源。仓库给出的标准骨架如下:
// functions/_worker.js export default { async fetch(request, env, ctx) { const url = new URL(request.url); // 自定义路由 if (url.pathname.startsWith('/api/')) { return new Response('API response'); } // 必须:兜底服务静态资源 return env.ASSETS.fetch(request); } };详见 pages/api.md 与 pages-functions/api.md。
四、Bindings 不生效:env.BINDING为 undefined 或直接报错
症状:env.KV、env.DB等绑定取不到值,或运行时抛错。
常见原因:
wrangler.jsonc存在语法错误(注意该文件是 JSONC,允许注释);- 绑定 ID 配错(如 KV namespace ID、D1
database_id); - 本地缺少
.dev.vars(本地 Secret/Var 依赖它); - 类型定义与实际配置不同步(TypeScript 下表现尤为明显)。
解决步骤:
- 校验
wrangler.jsonc语法,参考 configuration.md 中的完整示例核对每种绑定的键名(kv_namespaces、d1_databases、r2_buckets、durable_objects.bindings、services、queues.producers、vectorize、ai.binding等); - 确认各绑定 ID 与云端资源一致;
- 本地开发创建
.dev.vars(切勿提交到版本库):
# .dev.vars (never commit) SECRET_KEY="local-secret-key" API_TOKEN="dev-token-123"- 重新生成类型:
npx wrangler types。
绑定名称是大小写敏感的,配置键名与代码中的env.X必须严格一致,这也是 pages-functions/gotchas.md 特别强调的常见误配点。
五、构建失败:部署在 Build 阶段挂掉
症状:Dashboard 上 Deployments 记录显示构建失败。
常见原因:
- 构建命令或输出目录配错;
- Node 版本不兼容(本地能过、CI 不过);
- 构建期缺少环境变量(如
NEXT_PUBLIC_*); - 超过 20 分钟构建超时;
- 内存不足(OOM)。
解决步骤:
- 打开Dashboard → Deployments → Build log查看具体报错;
- 核对构建设置中的 build command / output directory;
- 在仓库根目录添加
.nvmrc固定 Node 版本,避免环境漂移; - 为构建期补充所需环境变量;
- 优化构建(裁剪依赖、减小体积)以规避超时与 OOM。
限额参考:构建时长上限 20 分钟,单次部署文件数上限 20,000,单文件 25MB,详见下文限额表。
六、中间件不执行:_middleware.ts未生效
症状:写在中间件里的鉴权、加头、错误处理逻辑完全没有跑。
常见原因:
- 文件名不对(必须是带下划线前缀的
_middleware.ts,注意前缀下划线); - 没有导出
onRequest(或onRequest数组); - 处理链断裂:既没调用
next()也没返回Response,导致请求悬空。
解决步骤:
- 将文件重命名为
functions/_middleware.ts(作用域为全站),或functions/api/_middleware.ts(仅作用于/api/*); - 确保导出处理器:
// functions/_middleware.ts —— 单中间件 export const onRequest: PagesFunction = async (context) => { const response = await context.next(); response.headers.set('X-Custom-Header', 'value'); return response; }; // 链式中间件(按数组顺序执行) export const onRequest = [errorHandler, auth];- 每个中间件最终必须
return context.next()放行,或直接返回Response短路。
context.data是中间件间共享状态的载体,例如鉴权中间件可以把用户信息写入context.data.userId供下游函数读取,这是 pages/api.md 中的标准做法。
七、_headers/_redirects不生效
症状:配置的响应头或重定向规则没有生效。
常见原因:
- 这两个文件只作用于静态资源;由 Functions 生成的响应不会经过它们;
- 同名路径存在 Functions 路由时,Functions 优先,静态规则被覆盖;
- 文件存在语法错误;
- 超出限额(
_headers最多 100 条规则,_redirects最多 2,100 条:2,000 静态 + 100 动态)。
解决步骤:
- 语法自查。
_redirects支持状态码、splat 通配符与占位符:
/old-page /new-page 301 # 301 重定向 /blog/* /news/:splat 301 # Splat 通配符 /users/:id /members/:id 301 # 占位符 /api/* /api-v2/:splat 200 # 代理(不重定向)_headers按路径分组声明:
/secure/* X-Frame-Options: DENY X-Content-Type-Options: nosniff /api/* Access-Control-Allow-Origin: * /static/* Cache-Control: public, max-age=31536000, immutable- 确认目标资源是静态文件而非 Functions 输出;
- 若需要给 Functions 响应加头,应直接在函数返回的
Response对象上设置 header,例如在中间件里response.headers.set(...)。
八、TypeScript 类型错误:env一堆红线
症状:Function 代码里env.X报类型错误。
常见原因:
- 类型文件未生成;
- 手写的
Envinterface 与wrangler.jsonc中的绑定不一致。
解决步骤:
- 生成类型文件并固定输出位置:
npx wrangler types --path='./functions/types.d.ts'- 在
functions/tsconfig.json中把types指向生成的文件; - 确保
Envinterface 与实际绑定对应。以 D1 + KV 为例:
import type { PagesFunction } from '@cloudflare/workers-types'; interface Env { DB: D1Database; KV: KVNamespace; } export const onRequestGet: PagesFunction<Env> = async ({ env }) => { const user = await env.DB.prepare('SELECT * FROM users WHERE id = ?').bind(123).first(); return Response.json(user); };九、本地开发问题:dev server 起不来或绑定异常
症状:wrangler pages dev报错,或本地绑定行为与线上不一致。
常见原因:
- 端口被占用;
- 绑定未传入本地 dev server;
- 本地 HTTP 与线上 HTTPS 的协议差异导致行为不一致(例如安全 cookie、
Referer判断)。
解决步骤:
- 指定端口启动:
npx wrangler pages dev ./dist --port=3000; - 通过 CLI 传入绑定:
npx wrangler pages dev ./dist --kv KV --d1 DB=local-db-id,或在wrangler.jsonc中配置(本地环境会自动读取.dev.vars); - 留意 HTTP/HTTPS 差异,涉及协议判断的逻辑在本地调试时单独验证。
仓库 configuration.md 给出了完整的本地开发命令族,包括持久化状态与代理模式(SSR 框架用):
# 基础 npx wrangler pages dev ./dist # 带绑定 npx wrangler pages dev ./dist --kv KV --d1 DB=local-db-id # 远程绑定(生产数据,慎用) npx wrangler pages dev ./dist --remote # 状态持久化 npx wrangler pages dev ./dist --persist-to=./.wrangler/state/v3 # 代理模式(SSR 框架) npx wrangler pages dev -- npm run dev十、性能问题:响应慢或触发 CPU 限额
症状:请求响应缓慢,或日志出现 "Request exceeded CPU limit"。
常见原因:
- Functions 被不必要地调用在静态资源上(路由过宽);
- 冷启动(冷启动延迟);
- 超出 CPU 限额(Free 10ms/req,Workers Paid 30ms/req);
- 打包体积过大。
解决步骤:
- 通过
_routes.json的exclude把静态资源排除在 Functions 之外——静态请求免费且不占 CPU 配额; - 优化热路径:减少同步阻塞、合并 I/O、优先用
await并发; - 保持 bundle < 1MB(Free 脚本大小上限 1MB 压缩后,Paid 10MB),必要时做 tree-shaking、动态 import、代码分割。
参考 pages-functions/gotchas.md 的最佳实践:用 KV 做缓存、D1 做关系数据、R2 放大文件,并设置合理的Cache-Control头。
十一、框架适配:哪些能用、哪些已废弃
⚠️ 已废弃框架(2024 年后无维护)
Next.js:官方适配器@cloudflare/next-on-pages已废弃且不再维护。
- 问题:2024 年后无更新;与 Next.js 15+ 不兼容;缺少 App Router 特性;
- 原因:Cloudflare 已停止官方支持,社区 fork 存在但能力有限;
- 解决方案:
- 推荐:改用 Vercel 托管(Next.js 官方宿主);
- 进阶:基于 Workers 自定义适配器自托管(复杂且不受支持);
- 迁移:切换到 SvelteKit/Nuxt(开发体验相似,Pages 完整支持)。
Remix:官方适配器@remix-run/cloudflare-pages已废弃。
- 问题:Remix 团队停止维护,与 Remix v2+ 存在兼容性问题;
- 原因:Remix 团队废弃了全部框架适配器;
- 解决方案:
- 推荐:迁移到 SvelteKit(类似的文件路由,更好的 DX);
- 备选:使用 Astro(静态优先、可选 SSR);
- 兜底:继续使用废弃适配器(但无后续支持)。
✅ 受支持框架(2026 状态)
| 框架 | 配置方式 | 绑定访问入口 |
|---|---|---|
| SvelteKit | @sveltejs/adapter-cloudflare,svelte.config.js设platform: 'cloudflare' | server load 函数中的platform.env |
| Astro | 内置 Cloudflare 适配器 | Astro.locals.runtime.env |
| Nuxt | nuxt.config.ts设nitro.preset: 'cloudflare-pages' | event.context.cloudflare.env |
| Qwik / Solid Start | 内置或官方 Cloudflare 适配器 | 参见各框架文档 |
框架集成代码示例详见 patterns.md,例如 SvelteKit 的+page.server.ts中platform.env.DB.prepare(...)、Astro 前端组件中的Astro.locals.runtime.env、Nuxt 的event.context.cloudflare.env.DB。
十二、调试技巧:日志与实时追踪
在函数代码中埋点打印请求、环境与路由参数:
// 记录请求详情 console.log('Request:', { method: request.method, url: request.url }); console.log('Env:', Object.keys(env)); console.log('Params:', params);实时查看线上日志:
npx wrangler pages deployment tail --project-name=my-project还可以按状态过滤(如只看错误):
npx wrangler pages deployment tail --status error若需要定位生产环境下的类型/堆栈问题,可在wrangler.jsonc中开启源码映射:{ "upload_source_maps": true }。
十三、Smart Placement 疑难
Smart Placement 会根据流量模式自动优化函数执行位置,配置方式见 configuration.md,其排障细节与 smart-placement/gotchas.md 一致,常见问题如下。
冷启动延迟增加
- 问题:开启 Smart Placement 后首批请求变慢;
- 原因:系统处于学习流量模式的初始优化期;
- 解决:部署后 24–48 小时内属预期行为,持续监控延迟趋势即可。
响应时间不稳定
- 问题:初始部署期间各请求延迟波动明显;
- 原因:Smart Placement 正在测试不同执行位置以寻找最优落点;
- 解决:学习期属正常现象,流量模式形成后(约 1–2 天)会趋于稳定。
开启后无性能提升
- 问题:启用 Smart Placement 但延迟没有下降;
- 原因:流量在全球均匀分布,或不存在数据本地性约束(如数据都在单一中心区域);
- 解决:Smart Placement 对数据集中(D1/DO)或区域集中流量最有效;若无收益,直接关闭。
显式关闭:
{ "placement": { "mode": "off" } } // 或直接删除 placement 字段,效果相同关键限制:仅影响 fetch 处理器
Smart Placement只对fetch处理器生效,Service Bindings 的 RPC 方法(WorkerEntrypoint)完全不受影响,因为 RPC 绕过了fetch入口。需要优化后端 RPC 延迟时,应改用 fetch 形式的 Service Binding。此外 Smart Placement 需要 Wrangler 2.20.0+ 且仅在生产环境生效(本地wrangler dev不生效,需用wrangler deploy --env staging验证),分析期最长 15 分钟,期间会路由约 1% 请求不做优化用于基线对比。
十四、远程绑定(--remote)注意事项
本地开发通过--remote直连生产绑定,方便验证,但代价是直写生产数据。
误改生产数据
- 问题:本地
--remote开发意外修改了生产库/KV; - 原因:远程绑定直连生产资源,写入是真实的;
- 解决:
--remote仅用于读为主的调试;- 测试请单独创建 preview 环境;
- 开发期间绝不用
--remote做写操作。
认证错误
- 问题:
npx wrangler pages dev --remote报 "Unauthorized" 或认证错误; - 原因:未登录、会话过期或账号权限不足;
- 解决:
npx wrangler login重新认证;- 确认账号对项目和绑定有访问权限;
- 核对绑定 ID 与生产配置一致。
本地开发变慢
- 问题:
--remote下本地 dev server 变慢; - 原因:每个请求都会网络调用生产绑定;
- 解决:开发期用本地绑定,仅在最终验证时使用
--remote。
十五、常见错误速查表
| 错误信息 | 原因 | 解决 |
|---|---|---|
| "Module not found" | 依赖未打包或构建输出错误 | 检查构建输出目录,确保依赖被打包 |
| "Binding not found" | 绑定未配置或类型不同步 | 核对 wrangler.jsonc,运行npx wrangler types |
| "Request exceeded CPU limit" | 代码执行过慢或计算密集 | 优化热路径;升级 Workers Paid |
| "Script too large" | 打包体积超限 | Tree-shake、动态 import、代码分割 |
| "Too many subrequests" | 超过单请求 50 次子请求上限 | 合并或减少 fetch 调用 |
| "KV key not found" | Key 不存在或 namespace 配错 | 核对 namespace 与环境是否匹配 |
| "D1 error" | database_id错误或缺少迁移 | 核对配置;运行wrangler d1 migrations list |
补充几个 Function 侧的典型报错(pages-functions/gotchas.md):
- 函数超时:通常是同步阻塞或漏写
await,所有 I/O 必须 async/await,后台任务用ctx.waitUntil(); - 生产环境 Secret 缺失:
.dev.vars仅本地生效,生产 Secret 必须通过 Dashboard 或wrangler pages secret put单独设置:echo "value" | npx wrangler pages secret put SECRET_KEY --project-name=my-project npx wrangler pages secret list --project-name=my-project npx wrangler pages secret delete SECRET_KEY --project-name=my-project
十六、限额参考(2026 年 1 月)
| 资源 | Free | Paid |
|---|---|---|
| Functions 请求 | 100k/天 | 无限(按量计费) |
| Function CPU 时间 | 10ms/req | 30ms/req(Workers Paid) |
| Function 内存 | 128MB | 128MB |
| 脚本体积 | 1MB(压缩) | 10MB(压缩) |
| 子请求数 | 50/req | 1,000/req(Workers Paid) |
| 部署次数 | 500/月 | 5,000/月 |
| 单次部署文件数 | 20,000 | 20,000 |
| 单文件大小 | 25MB | 25MB |
| 构建时长 | 20min | 20min |
| 重定向规则 | 2,100(2,000 静态 + 100 动态) | 同左 |
| 响应头规则 | 100 | 100 |
路由规则(_routes.json) | 100(每条 ≤100 字符) | 100 |
提示:Functions 使用 Workers 运行时,Workers Paid 计划可提升上述限额;Free 计划足以覆盖大多数项目;静态请求永远免费(不占用 Functions 配额)。命中 CPU 限额时,优先优化热路径,或升级 Workers Paid。
十七、获取帮助
- 查阅 Cloudflare Pages 官方文档;
- 在 Cloudflare 社区 Discord 的 #functions 频道检索;
- 浏览 Workers Examples 官方示例库;
- 查阅所用框架的适配器/文档。
若需要在本仓库内继续深入,建议按如下顺序阅读同目录系列文档:pages/README.md(总览与快速开始)→ pages/configuration.md(wrangler.jsonc、绑定、静态配置文件)→ pages/api.md(Functions API、路由、上下文)→ pages/patterns.md(常见实现模式);函数侧细节可对照 pages-functions/ 系列文档。
【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考