这次博客部署后,我把 Cloudflare Pages 提供的地址绑定成了自定义域名:
https://field-notes-blog.pages.dev
https://blog.labnote.top
前者可以正常打开,后者却一直显示 404。最开始很容易怀疑 DNS 或 SSL,但最后真正的问题其实出在 Pages 的生产分支。
先不要猜,先判断错误发生在哪一层
我把访问链路拆成四层:
- DNS 是否把域名解析到 Cloudflare?
- HTTPS 证书是否正常?
- 自定义域名是否绑定到了正确的 Pages 项目?
- 这个项目的生产分支上是否真的有网站内容?
这样做的好处是,每一步都有一个可以验证的证据,不会把所有问题都归结成“Cloudflare 配置错了”。
DNS 正常,不代表网站一定正常
查询 blog.labnote.top 的 DNS,得到的是 Cloudflare 的 IP:
104.21.24.130
172.67.218.238
这说明域名已经到达 Cloudflare。接着用 HTTPS 访问,返回的是:
HTTP/1.1 404 Not Found
Server: cloudflare
这个结果很关键。它说明 TLS 握手已经成功,请求也已经进入 Cloudflare。问题不是证书,也不是域名没有解析,而是 Cloudflare 没找到这个域名对应的网站内容。
找到 Pages 项目和生产分支
查看 Pages 项目后,发现项目实际名称是:
blog-labnote
它绑定了两个域名:
field-notes-blog.pages.dev
blog.labnote.top
项目名称和 pages.dev 域名不一定相同,这一点容易让人误以为自己操作了两个项目。
接着查看部署记录,发现项目里同时存在两个分支:
main
master
之前手动发布博客时,内容被部署到了 main。但是这个 Pages 项目的生产分支是 master,而自定义域名跟随的是生产分支。
结果就变成了:
field-notes-blog.pages.dev -> main -> 有博客内容
blog.labnote.top -> master -> 空部署 -> 404
这也解释了为什么两个域名的表现不一样。
修复方式
解决方法不是重新改 DNS,而是把同一份构建产物发布到正确的生产分支:
npm run build
npx wrangler pages deploy dist \
--project-name blog-labnote \
--branch master
发布完成后,再访问自定义域名,返回 HTTP 200,首页和文章内容都恢复正常。
Cloudflare Pages 的自定义子域名需要在 Pages 项目中完成绑定,并配置指向 Pages 域名的 CNAME。只添加 DNS 记录而没有在 Pages 中关联项目,也可能导致域名无法正常工作。详见 Cloudflare Pages 自定义域名文档。
这次学到的排错顺序
以后遇到类似问题,我会按这个顺序检查:
- 用
dig检查 DNS 是否解析到了正确的平台。 - 用
curl -I区分 TLS 错误、重定向、404 和 5xx。 - 在 Pages 中确认自定义域名的状态是否为 active。
- 查看项目真正的名称和生产分支。
- 分别访问生产域名和每个部署的预览地址,比较它们对应的内容。
- 确认构建产物被发布到了自定义域名实际使用的分支。
最后一个提醒
一个 Pages 项目同时使用 Git 集成和 Wrangler 手动部署时,要特别注意分支。Git 可能从 master 自动发布,而本地命令却把文件上传到了 main,两套流程就会产生不同版本。
更稳妥的做法是统一发布方式。如果生产分支是 master,以后就始终使用:
npm run build
npx wrangler pages deploy dist \
--project-name blog-labnote \
--branch master
域名只是入口,分支才决定入口最终看到什么内容。