
【免费下载链接】autoskillsOne command. Your entire AI skill stack. Installed.项目地址https://gitcode.com/gh_mirrors/au/autoskills点击查看免费下载导读本文基于 autoskills 仓库内置的 Cloudflare 技能参考packages/autoskills/skills-registry/cloudflare/references/static-assets编写系统讲解如何在 Cloudflare Workers 上托管与配置静态资源涵盖wrangler.jsonc配置、ASSETS绑定 API、SPA/SSG/全栈应用的路由模式以及与 Cloudflare Pages 的选型对比。读完本文你将能够独立完成一个 Worker 静态资源项目的搭建、路由编排、缓存优化与故障排查。一、快速上手三步完成静态资源部署Cloudflare Workers Static Assets 允许你把静态文件HTML、CSS、JS、图片等直接托管到 Workers 之上并通过ASSETS绑定在代码中访问。最小配置只需要声明一个assets.directory。1. 配置wrangler.jsonc// wrangler.jsonc { name: my-app, main: src/index.ts, compatibility_date: 2025-01-01, assets: { directory: ./dist } }其中directory指向构建产物目录如./dist、./public、./buildcompatibility_date建议使用新项目当前日期。2. 在 Worker 入口转发请求到ASSETS绑定// src/index.ts export default { async fetch(request: Request, env: Env): PromiseResponse { return env.ASSETS.fetch(request); } };3. 部署wrangler deployenv.ASSETS是一个Fetcher对象调用其fetch即可读取绑定目录内的文件wrangler deploy会把./dist目录随 Worker 一并上传。二、选型Workers Static Assets 还是 Cloudflare Pages在动手之前需要先明确使用场景。Workers Static Assets 与 Cloudflare Pages 都提供静态托管能力但定位不同维度Workers Static AssetsCloudflare Pages适用场景混合应用静态 动态 API静态站点、SSGWorker 控制力完整的路由控制权受限Functions配置方式代码优先、灵活基于 Git、约定式动态路由Worker 优先模式Functions_functions/最佳场景全栈应用、带 API 的 SPAJamstack、静态文档决策树需要自定义路由逻辑→ 选 Workers Static Assets纯静态站点或 SSG→ 选 Cloudflare PagesAPI 路由 SPA→ 选 Workers Static Assets使用框架Next.js、Nuxt、Remix→ 选 Cloudflare Pages一句话概括当你的应用需要静态文件 动态逻辑混合时Workers Static Assets 让 Worker 代码与静态资源在同一运行时内协同工作路由完全由你掌控。三、配置详解configuration.md3.1 完整配置项{ name: my-worker, main: src/index.ts, compatibility_date: 2025-01-01, assets: { directory: ./dist, binding: ASSETS, not_found_handling: single-page-application, html_handling: auto-trailing-slash, run_worker_first: [/api/*, !/api/docs/*] } }各配置键的作用directorystring必填静态资源目录路径如./dist、./public、./build。bindingstring可选Worker 代码中访问资源的绑定名称如env.ASSETS默认值为ASSETS。not_found_handlingstring可选资源未命中时的行为详见 3.2。html_handlingstring可选HTML 文件 URL 尾部斜杠的行为详见 3.3。run_worker_firstboolean 或 string[]可选哪些路由先经过 Worker 再查静态资源详见 3.4。3.2 not_found_handling 模式控制请求的资源不存在时返回什么模式行为适用场景single-page-application非资源请求回退到/index.htmlReact、Vue、Angular 等 SPA404-page存在/404.html则返回之否则返回 404带自定义错误页的静态站点none缺失资源直接返回 404API 优先或自定义路由3.3 html_handling 模式控制 HTML 文件的尾部斜杠行为模式/page访问/page/访问适用场景auto-trailing-slash若存在/page/index.html则 301 重定向到/page/直接返回/page/index.html默认值SEO 友好force-trailing-slash总是重定向到/page/存在则直接返回需要统一尾部斜杠drop-trailing-slash存在则直接返回重定向到/page更干净的 URLnone不做任何改写不做任何改写自定义路由逻辑默认值auto-trailing-slash它能在不加重定向的前提下让/page/正确映射到/page/index.html。3.4 run_worker_first路由优先级编排该配置决定哪些请求先进入 Worker 代码、再查询静态资源是静态优先与Worker 优先两种架构的开关。布尔语法全量 Worker 优先{ assets: { run_worker_first: true // 所有请求都先进入 Worker } }数组语法推荐按路由精准控制{ assets: { run_worker_first: [ /api/*, // 正向模式匹配 API 路由 /admin/*, // 匹配后台路由 !/admin/assets/* // 负向模式排除后台静态资源 ] } }模式规则Glob 通配*匹配任意字符**匹配任意路径段负向模式以!前缀排除优先级负向模式覆盖正向模式默认值false静态资源直接返回不经过 Worker。决策建议API 优先应用静态资源很少→ 用true混合应用API 静态资源→ 用数组模式静态优先站点动态路由极少→ 用false让绝大多数请求直接命中 CDN 缓存。3.5 .assetsignore 排除文件与.gitignore同语法在项目根目录创建.assetsignore即可从上传中排除文件# .assetsignore _worker.js *.map *.md node_modules/ .git/常见用途_worker.js排除 Worker 代码混入静态资源、*.map排除 source map、*.md排除文档、开发产物一律不传。3.6 Vite 插件集成Vite 项目可直接使用官方插件在构建与开发阶段无缝衔接静态资源// vite.config.ts import { defineConfig } from vite; import { cloudflare } from cloudflare/vite-plugin; export default defineConfig({ plugins: [ cloudflare({ assets: { directory: ./dist, binding: ASSETS } }) ] });能力特性开发期自动识别资源、资源热更新HMR、生产构建集成。版本前提需要 Wrangler 4.0.0 与cloudflare/vite-plugin1.0.0。3.7 关键兼容性日期日期特性影响2025-04-01导航请求优化SPA 导航请求跳过 Worker 调用降低费用新项目应使用当前日期作为compatibility_date完整兼容性日期清单以 Cloudflare 官方文档为准。3.8 环境差异化配置利用wrangler.jsonc的env分段为不同环境设置不同行为{ name: my-worker, assets: { directory: ./dist }, env: { staging: { assets: { not_found_handling: 404-page } }, production: { assets: { not_found_handling: single-page-application } } } }按环境部署wrangler deploy --env staging四、ASSETS 绑定 APIapi.md4.1 类型定义ASSETS绑定通过Fetcher接口暴露给 Workerinterface Env { ASSETS: Fetcher; } interface Fetcher { fetch(input: RequestInfo | URL, init?: RequestInit): PromiseResponse; }4.2 四种 fetch 调用方式// 1. 原样转发整个请求 await env.ASSETS.fetch(request); // 2. 字符串路径host 被忽略只取路径 await env.ASSETS.fetch(https://any-host/path/to/asset.png); // 3. URL 对象 await env.ASSETS.fetch(new URL(/index.html, request.url)); // 4. 构造 Request 对象 await env.ASSETS.fetch(new Request(new URL(/logo.png, request.url), { method: GET, headers: request.headers }));关键行为字符串/URL 输入的 host 会被忽略只有路径参与资源解析方法必须是 GET其他方法返回 405请求头会透传并影响响应返回值是标准Response对象。4.3 路径解析规则// 下面三种写法解析到同一个资源 env.ASSETS.fetch(https://example.com/logo.png) env.ASSETS.fetch(https://ignored.host/logo.png) env.ASSETS.fetch(/logo.png)资源路径相对assets.directory配置的目录解析。4.4 影响响应的请求头请求头效果Accept-Encoding控制压缩算法gzip、brotliRange启用分段内容返回 206If-None-Match基于 ETag 的条件请求If-Modified-Since基于修改时间的条件请求自定义头会透传但不影响资源服务行为。4.5 方法支持方法支持响应GET✅ 支持返回资源内容HEAD✅ 支持仅返回响应头无 bodyPOST、PUT等❌ 不支持405 Method Not Allowed4.6 响应行为Content-Type 推断根据文件扩展名自动推断Content-Type扩展名Content-Type.htmltext/html; charsetutf-8.csstext/css.jsapplication/javascript.jsonapplication/json.pngimage/png.jpg、.jpegimage/jpeg.svgimage/svgxml.woff2font/woff24.7 默认响应头Content-Type: inferred ETag: hash Cache-Control: public, max-age3600 Content-Encoding: br (如果支持且收益明显)缓存默认值多数资源缓存 1 小时max-age3600可通过 Worker 响应转换覆盖见本文第五部分的模式 4 与模式 12。4.8 压缩与 ETag压缩根据Accept-Encoding自动选择优先 Brotlibr其次 Gzipgzip客户端不支持或资源过小时不压缩。ETag基于内容哈希生成形如a3b2c1d4e5f6...用于If-None-Match条件请求命中时返回304 Not Modified。4.9 错误响应状态码触发条件行为404资源不存在body 取决于not_found_handling配置405非 GET/HEAD 方法返回{ error: Method not allowed }416Range 头非法Range 不可满足其中 404 行为与配置的对应关系// not_found_handling: single-page-application // 返回 /index.html状态码 200 // not_found_handling: 404-page // 存在 /404.html 则返回之否则返回 404 响应 // not_found_handling: none // 直接返回 404 响应4.10 高级用法修改响应覆盖缓存头、追加自定义头const response await env.ASSETS.fetch(request); // 克隆并修改 return new Response(response.body, { status: response.status, headers: { ...Object.fromEntries(response.headers), Cache-Control: public, max-age31536000, X-Custom: value } });错误处理const response await env.ASSETS.fetch(request); if (!response.ok) { // 资源不存在或出错 return new Response(Custom error page, { status: 404 }); } return response;条件服务const url new URL(request.url); // 根据条件返回不同资源 if (url.pathname /) { return env.ASSETS.fetch(/index.html); } return env.ASSETS.fetch(request);五、12 个实战模式patterns.md模式 1直接转发请求到静态资源export default { async fetch(request: Request, env: Env): PromiseResponse { return env.ASSETS.fetch(request); } };模式 2按路径取特定资源const response await env.ASSETS.fetch(https://assets.local/logo.png);模式 3改写请求后再取资源const url new URL(request.url); url.pathname /index.html; return env.ASSETS.fetch(new Request(url, request));模式 4转换资源响应const response await env.ASSETS.fetch(request); const modifiedResponse new Response(response.body, response); modifiedResponse.headers.set(X-Custom-Header, value); modifiedResponse.headers.set(Cache-Control, public, max-age3600); return modifiedResponse;模式 5条件化资源服务export default { async fetch(request: Request, env: Env): PromiseResponse { const url new URL(request.url); if (url.pathname /) { return env.ASSETS.fetch(/index.html); } return env.ASSETS.fetch(request); } };模式 6SPA API 路由最常见的全栈模式export default { async fetch(request: Request, env: Env): PromiseResponse { const url new URL(request.url); if (url.pathname.startsWith(/api/)) { return handleAPI(request, env); } return env.ASSETS.fetch(request); } }; async function handleAPI(request: Request, env: Env): PromiseResponse { return new Response(JSON.stringify({ status: ok }), { headers: { Content-Type: application/json } }); }配套配置设置run_worker_first: [/api/*]让 API 请求先进 Worker、静态资源直接走 CDN。模式 7受保护资源的鉴权拦截export default { async fetch(request: Request, env: Env): PromiseResponse { const url new URL(request.url); if (url.pathname.startsWith(/admin/)) { const session await validateSession(request, env); if (!session) { return Response.redirect(/login, 302); } } return env.ASSETS.fetch(request); } };配套配置run_worker_first: [/admin/*]。模式 8安全响应头export default { async fetch(request: Request, env: Env): PromiseResponse { const response await env.ASSETS.fetch(request); const secureResponse new Response(response.body, response); secureResponse.headers.set(X-Frame-Options, DENY); secureResponse.headers.set(X-Content-Type-Options, nosniff); secureResponse.headers.set(Content-Security-Policy, default-src self); return secureResponse; } };模式 9基于 Cookie 的 A/B 测试export default { async fetch(request: Request, env: Env): PromiseResponse { const cookies request.headers.get(Cookie) || ; const variant cookies.includes(variantb) ? b : a; const url new URL(request.url); if (url.pathname /) { return env.ASSETS.fetch(/index-${variant}.html); } return env.ASSETS.fetch(request); } };模式 10基于 Accept-Language 的国际化路由export default { async fetch(request: Request, env: Env): PromiseResponse { const locale request.headers.get(Accept-Language)?.split(,)[0] || en; const url new URL(request.url); if (url.pathname /) { return env.ASSETS.fetch(/${locale}/index.html); } if (!url.pathname.startsWith(/${locale}/)) { url.pathname /${locale}${url.pathname}; } return env.ASSETS.fetch(url); } };模式 11OAuth 回调处理export default { async fetch(request: Request, env: Env): PromiseResponse { const url new URL(request.url); if (url.pathname /auth/callback) { const code url.searchParams.get(code); if (code) { const session await exchangeCode(code, env); return new Response(null, { status: 302, headers: { Location: /, Set-Cookie: session${session}; HttpOnly; Secure; SameSiteLax } }); } } return env.ASSETS.fetch(request); } };配套配置run_worker_first: [/auth/*]。模式 12缓存控制覆盖内容哈希文件名识别export default { async fetch(request: Request, env: Env): PromiseResponse { const response await env.ASSETS.fetch(request); const url new URL(request.url); // 不可变资源内容哈希文件名 if (/\.[a-f0-9]{8,}\.(js|css|png|jpg)$/.test(url.pathname)) { return new Response(response.body, { ...response, headers: { ...Object.fromEntries(response.headers), Cache-Control: public, max-age31536000, immutable } }); } return response; } };六、最佳实践、常见错误与性能优化gotchas.md6.1 四条核心最佳实践1. 用选择性 Worker-First 路由替代全量true{ assets: { run_worker_first: [ /api/*, // API 路由 /admin/*, // 后台区域 !/admin/assets/* // 排除后台静态资源 ] } }收益减少 Worker 调用次数、降低成本、提升资源交付性能。2. 利用导航请求优化SPA 场景将compatibility_date设为2025-04-01或更新配合single-page-application导航请求将跳过 Worker 调用降低成本{ compatibility_date: 2025-04-01, assets: { not_found_handling: single-page-application } }3. 绑定类型安全始终为环境变量声明类型interface Env { ASSETS: Fetcher; }4. 使用.assetsignore减少上传体积*.map *.md .DS_Store node_modules/6.2 常见错误排查错误现象原因解决方案Asset not found资源不在目录、路径错误或未部署确认资源存在、检查路径大小写、必要时重新部署Worker not invoked for asset资源被直接服务run_worker_first未配置在run_worker_first中纳入对应路由429 Too Many Requests on free tier模式过宽导致大量请求进 Worker触及免费层限制10 万请求/天使用更精准的模式与负向排除或升级付费计划Smart Placement increases latencyrun_worker_firsttrue Smart Placement 将所有请求路由到单一智能放置点改用数组语法选择性路由或对资源密集应用关闭 Smart PlacementCF-Cache-Status header unreliable出于隐私原因该头为概率性注入关键路由逻辑不要依赖它改用 ETag、age 等信号JWT expired during deployment大规模资源部署超过 JWT 令牌生命周期升级到 Wrangler 4.34.0自动刷新令牌或减少资源数量Cannot use assets with site旧site配置与新assets配置冲突迁移到assets配置从wrangler.jsonc移除site键Assets not updating after deployment浏览器或 CDN 缓存了旧资源硬刷新CmdShiftR / CtrlF5、启用缓存破坏哈希文件名、用wrangler tail确认部署完成6.3 限制与版本要求资源限制资源/限制免费版付费版备注单文件最大尺寸25 MiB25 MiB按文件计资源总数20,000100,000100,000 上限需要 Wrangler 4.34.02025 年 9 月Worker 调用量10 万/天1000 万/月用run_worker_first模式优化资源存储无限无限包含在服务内版本要求特性最低 Wrangler 版本10 万文件上限付费4.34.0Vite 插件4.0.0 cloudflare/vite-plugin 1.0.0导航请求优化4.0.0 compatibility_date 2025-04-016.4 性能优化建议1. 内容哈希文件名启用长期缓存app.a3b2c1d4.js styles.e5f6g7h8.cssVite、Webpack、Parcel 等主流打包器默认自动生成哈希文件名。2. 最小化 Worker 调用能直接服务资源就尽量不经过 Worker仅对动态路由开放{ assets: { // 只为动态路由调用 Worker run_worker_first: [/api/*, /auth/*] } }3. 分级利用浏览器缓存// 带版本号/哈希的资源 Cache-Control: public, max-age31536000, immutable // HTML需要频繁校验 Cache-Control: public, max-age0, must-revalidate4. 用.assetsignore精简上传内容详见 configuration.md 对应小节减少上传时间。七、技能在 autoskills 仓库中的定位与分发机制本文所述的 Cloudflare Static Assets 参考文档是 autoskills 仓库中cloudflare技能SKILL.md的组成部分位于references/static-assets/目录下与workers、pages、d1、durable-objects、workers-ai等参考并列供 AI Agent 处理 Cloudflare 开发任务时检索调用。该技能通过 skills-map.ts 中的技术探测规则被自动识别当项目中出现wrangler、cloudflare/workers-types、astrojs/cloudflare等依赖或存在wrangler.toml、wrangler.json、wrangler.jsonc配置文件时autoskills 即判定项目属于 Cloudflare 技术栈并自动安装cloudflare技能含本文的 static-assets 参考。整个技能分发链路是经过审计的技能文件被同步进仓库内建的 registryskills-registry/index.json每条目记录来源、commitSha与每个文件的 SHA-256 哈希validate-registry.mjs 在发布前逐一校验文件存在性与哈希一致性含bundleHash校验确保安装到用户项目中的文件与审计版本完全一致。运行npx autoskills后CLI 仅从该受审注册表下载与项目匹配的技能文件写入skills-lock.json记录来源与哈希。从源码结构看这套扫描技术栈 → 匹配技能 → 校验下载的流程正是 autoskills One command. Your entire AI skill stack. Installed. 的核心实现。八、建议阅读顺序本参考集共五份文档按序阅读可获得完整知识链README.md —— 总览与选型决策即本文骨架configuration.md —— 安装、部署与wrangler.jsonc全部配置项api.md ——ASSETS绑定 API、请求/响应处理细节patterns.md —— SPA、API 路由、鉴权、A/B 测试等常用模式gotchas.md —— 限制、错误排查与性能建议。掌握以上内容后你即可在 Cloudflare Workers 上自由编排静态资源 动态逻辑的混合应用从最小配置的静态站点到带鉴权、A/B 测试、多语言路由的全栈 SPA再到精细化的缓存与成本优化全部有章可循。赞分享【免费下载链接】autoskillsOne command. Your entire AI skill stack. Installed.项目地址https://gitcode.com/gh_mirrors/au/autoskills点击查看免费下载相关推荐Cloudflare Workers 静态资源Static Assets部署与配置完全指南Cloudflare Workers 静态资源Static Assets部署与配置完全指南 Cloudflare Workers Static Assets人工智能AI 技能AI 插件Cloudflare Workers Static Assets 配置完全指南wrangler.jsonc 静态资源与 Worker 路由实战Cloudflare Workers Static Assets 配置完全指南wrangler.jsonc 静态资源与 Worker 路由实战 本指南以 sk人工智能AI 技能AI 插件使用 Cloudflare Workers Static Assets 部署静态资源从 wrangler.jsonc 配置到生产级实战指南使用 Cloudflare Workers Static Assets 部署静态资源从 wrangler.jsonc 配置到生产级实战指南 本指南基于 aut创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考