← 全部文章

独立开发 / FIELD NOTE

Cloudflare Pages 部署后 CSS 加载 404:按顺序排查这几个位置

Astro 或其他静态站部署到 Cloudflare Pages 后样式丢失,从资源路径、构建配置到缓存策略,按六步定位并修复问题。

Cloudflare Pages 部署流程图,标示资源路径检查的关键节点

把 Astro 或其他静态网站部署到 Cloudflare Pages 后打开页面发现只有 HTML,CSS 和 JS 全部返回 404。这个问题的根因只有几种可能,而且都在部署前和部署后的几个固定位置。按下面的顺序排查,大部分情况下不需要修改源代码。

先确认 404 的资源路径长什么样

打开浏览器开发者工具的网络面板(F12 → Network),刷新页面,找到返回红色的 CSS 或 JS 请求。看它的完整 URL:

正确:https://你的域名/_astro/style.abc123.css
错误:https://你的域名/articles/_astro/style.abc123.css

如果路径里多出了一层不该有的目录(比如文章路径被拼到了资源路径前面),说明资源引用路径出了问题。先记下这个错误的路径模式,后面每一步都用来验证修复是否成功。

第一步:检查构建产物中的资源路径

在本地已经构建完成后,打开 dist 目录,查看 HTML 文件中引用资源的路径。

# 进入构建输出目录
cd dist
# 查看首页引用的 CSS 路径
grep -oP 'href="[^"]*\.css"' index.html | head -5

输出示例:

href="/_astro/style.abc123.css"

这里的路径必须以 / 开头,指向站点根目录下的 _astro 文件夹。Cloudflare Pages 不会自动把相对路径转换成绝对路径。如果你的 HTML 里出现的是这样的路径:

href="_astro/style.abc123.css"

或者:

href="./_astro/style.abc123.css"

Cloudflare Pages 会在当前页面的相对位置查找这个文件,而不是从站点根目录开始找。在 /articles/some-post/ 这样的二级路径下,浏览器会请求 /articles/_astro/style.css,而这个文件并不存在。

修复方法:在 Astro 的 astro.config.mjs 中确认 build.assets 使用默认值或绝对路径前缀。大多数情况下不需要修改配置,只需要确认没有错误地设置了 basesite 字段。

在 Astro 项目中检查配置文件:

// astro.config.mjs
export default defineConfig({
  site: "https://你的域名.com",  // 这里填你的正式域名
  // 不要设置 base 字段,或者设置为 '/'
})

site 字段填正式域名后,构建产出的资源路径会自动加上正确的前缀。设置 base 为其他值反而会导致资源路径多出一层目录。

第二步:确认构建时没有使用错误的 base path

Cloudflare Pages 部署时有一个常见陷阱:如果你在本地开发时设置了 base: '/my-project/',构建出来的所有资源路径都会带上这个前缀。部署到 Cloudflare Pages 后,这些路径自然找不到对应文件。

查看 astro.config.mjs 中是否设置了 base

// 错误的配置——部署后资源全部 404
base: '/my-project/'

// 正确的配置——资源引用站点根目录
// 删除 base 行,或者设为 '/'

如果你确实需要 base 路径(比如部署到子路径下),必须同时确认 build.assets 的设置与 base 一致。但在 Cloudflare Pages 的标准部署中,不需要也不应该使用自定义 base

第三步:检查 Cloudflare Pages 的项目设置

进入 Cloudflare Dashboard → Pages 项目 → 设置 → 构建配置,确认以下三项:

  1. 构建命令npm run build
  2. 构建输出目录dist
  3. 根目录:留空(除非项目不在仓库根目录)

输出目录填错是最隐蔽的错误。如果填成了 dist 但构建产生的是 build 文件夹,Cloudflare 会部署一个空目录或错误目录。部署成功后打开页面,HTML 可能能加载(因为 Cloudflare 可能有 fallback),但所有资源请求打不到正确位置。

确认方法:在本地执行 npm run build 后,查看哪个目录产生了 HTML 和 _astro 文件夹,然后将这个目录名填入 Cloudflare Pages 的构建输出目录设置中。

第四步:用 Wrangler 预览排查

在部署到 production 前,先用 Wrangler 的本地预览功能检查资源加载:

npx wrangler pages dev dist

这会启动一个本地服务器,用 Cloudflare Pages 的运行时来模拟生产环境。打开浏览器访问 localhost:8788,查看页面 CSS 和 JS 是否正常加载。如果本地预览下资源就是 404,说明问题出在构建产物本身,而不是 Cloudflare 的部署环境。

如果本地预览正常但线上 404,问题更可能出在部署配置或缓存上。

第五步:检查 Cloudflare 缓存和 Auto Minify

Cloudflare Pages 默认会缓存静态资源。如果之前部署过一个有问题的版本,浏览器可能还缓存着旧的 HTML,而新的 CSS 文件名(带有新哈希值)和旧的不匹配。

执行一次硬刷新(Ctrl+Shift+R 或在开发者工具中勾选 Disable Cache 后刷新)。如果硬刷新后正常,说明是浏览器缓存问题。可以在 Cloudflare Dashboard 中触发一次缓存清除:

Cloudflare Dashboard → 缓存 → 配置 → 清除所有内容

另外检查 Cloudflare Dashboard 中是否开启了 Auto Minify。对于 Cloudflare Pages 项目,建议关闭 HTML、CSS 和 JS 的 Auto Minify,因为它可能与 Pages 自身的优化冲突,导致资源路径被错误修改。

第六步:检查 _headers 和 _redirects 文件

Cloudflare Pages 支持在 public 目录中放置 _headers_redirects 文件来定义自定义响应头和重定向规则。如果这两个文件的规则写错了,可能误拦截资源请求。

例如,一个错误的 _redirects 规则:

/articles/*  /  301

这条规则把所有 /articles/ 开头的请求都重定向到首页,CSS 和 JS 请求如果路径中包含 /articles/ 也会被错误重定向。

检查项目 public/ 目录下的 _headers_redirects 文件,确保它们的规则不会意外覆盖资源请求路径。如果不确定,暂时移除这两个文件,重新部署,看资源是否恢复正常。

第七步(最终确认):对比部署 ZIP 的结构

Cloudflare Pages 的 Direct Upload 方式依赖你上传的 ZIP 文件结构。如果用 CI 或手动上传,可以解压部署包确认内部结构:

# 解压部署包
unzip -l deploy.zip | head -30

检查输出的文件列表中,_astro/ 文件夹及其中的 CSS/JS 文件是否存在于正确的层级。如果 ZIP 里缺少这些文件,说明构建步骤没生成完整产物,不是部署配置的问题。

常见问题

修改配置后重新部署,CSS 还是 404?

Cloudflare Pages 的缓存最长可能持续 24 小时。部署后立即在 Cloudflare Dashboard 中清除全站缓存。另外检查新版部署是否成功覆盖了旧版——在 Pages Dashboard 的部署列表中确认最新的部署状态是 Success。

本地和预览环境正常,部署后还是 404?

确认 astro.config.mjs 中的 site 字段填写的域名是否与 Cloudflare Pages 分配的域名一致。如果本地用了 localhost,预览用了 127.0.0.1,但 site 填的是其他域名,构建工具会基于 site 生成资源路径前缀,部署到 Cloudflare 后可能路径不匹配。

Cloudflare Pages 支持 SPA 路由模式吗?

支持,但需要在 public/_redirects 文件中添加 SPA fallback 规则。如果 SPA 配置过了但 CSS 仍然 404,可以暂时移除 SPA 规则,排查完资源路径问题再加回来。

结论

Cloudflare Pages 部署后 CSS 404 的原因集中在四个位置:构建时的资源引用路径、Cloudflare Pages 的项目配置、缓存和 _headers/_redirects 规则。按本文顺序排查,通常在前三步就能定位问题。不需要修改源代码框架,也不需要安装额外插件。如果你还在验证网站方向的阶段,可以先走一遍可盈利网站验证路线,确认需求再投入部署细节。

关于作者

记录独立开发、内容增长和网站商业化过程中的真实问题、验证路径与复盘。

了解本站的写作与验证方法 →

DISCUSSION

评论

0 条

正在读取评论…

留下评论

无需登录。评论通过审核后公开,邮箱不会展示。