刷新404
提示
记录一次部署 teek 静态网站,推送到服务器刷新 404 的问题
问题背景
- 使用
teek
构建静态网站,推送到服务器后,访问首页正常刷新不会出现 404,点击网站任何的文章也可以正常访问,但是点击任意文章进来后,再次刷新网页会出现 404,这是为什么呢?
问题分析
回忆一下静态网站的工作方式。静态网站通常由 HTML、CSS 和 JavaScript 文件组成,部署在服务器上后,服务器会根据请求的 URL 返回对应的文件。如果直接访问一个存在的路径,比如首页(/),服务器会返回 index.html。而当用户在客户端通过 JavaScript 进行路由跳转时,比如点击链接进入文章页面,这时候 URL 改变了,但并没有向服务器请求新的页面,而是由前端路由处理的。
问题出现在刷新文章页面时出现 404。这可能是因为当用户刷新页面时,浏览器会向服务器请求当前 URL 对应的资源,比如
/pages/56b4d5
。而服务器上并没有这个路径的实际文件,因此返回 404。经过排查实际是有这个路径的,直接点击链接可以访问文章页面,说明前端路由工作正常,只是刷新时服务器找不到对应的文件,所以排除掉。检查 nginx 配置文件,是有配置 404 页面的处理,
try_files $uri $uri.html $uri/ =404;
同时也重启 nginx 配置文件,但是还是不行。网站使用了 cdn 网络分发服务,尝试把 cdn 服务关闭,由于 cdn 是有缓存时间的,等待 10 分钟左右测试观测,刷新不会出现 404,说明是 cdn 的问题。再次把 cndn 服务打开,刷新页面还是会出现 404。
由此可以百分比确实是 cdn 的配置问题
。那么问题来了,既然是 cnd 配置有问题,那么具体是哪个地方配置有问题呢?
问题求助
- 既然确定到是 cnd 的问题,由于 cdn 服务商使用的是阿里云,那么就直接去阿里云官网找人工客服寻求帮助
- 找到阿里云的人工客服后,和客服说明的问题具体情况,客服第一时间帮我提了工单。大概 3 分钟阿里云技术工程师来电,和阿里云工程师描述问题背景以及具体情况
- 首先阿里云工程师让我把 cdn 开启,此时
CNAME
状态开启,域名解析CNAME
状态是关闭的,A 记录类型是开启的,测试 PC、移动端点击任意文章正常,刷新无 404 - 再次把域名解析
CNAME
状态开启,A 记录类型关闭,等待 10 分钟左右观察,问题出现,测试 PC端正常、但是移动端点击任意文章正常,刷新后出现 404
问题原因
- 阿里云工程师分析,由于网站使用了不同的接口请求,网站把请求的接口给缓存了
- 回源 HOST 未开启: CDN 默认回源时,可能使用 加速域名(如
xxx.example.com
)作为HOST
头发送给源站服务器。- 若源站服务器(如 Nginx)配置了 域名绑定(即只响应特定域名的请求),当回源
HOST
与源站域名(如teek.seasir.top
)不匹配时,源站会拒绝请求或返回 404。 - 结果:CDN 无法正确回源获取
index.html
,反而可能缓存了源站的 404 响应。
- 若源站服务器(如 Nginx)配置了 域名绑定(即只响应特定域名的请求),当回源
- 回源 SNI 未配置: 如果源站使用 HTTPS,CDN 回源时需通过 SNI(Server Name Indication) 指定域名,以匹配源站证书的域名(
teek.seasir.top
)。- SNI 未配置时,CDN 可能使用默认域名或 IP 回源,导致 SSL/TLS 握手失败(证书域名不匹配),回源请求被阻断。
- 结果:CDN 无法与源站建立安全连接,进一步加剧了 404 问题。
- 缓存策略未限制: 若根目录
/
未设置缓存过期时间(或默认缓存),CDN 会将错误响应(如 404)缓存下来。- 用户刷新页面时,CDN 直接返回缓存的 404 页面,而非重新回源请求
index.html
。
- 用户刷新页面时,CDN 直接返回缓存的 404 页面,而非重新回源请求
问题解决
- 把 cnd 默认回源配置 HOST 开启,域名类型是加速域名
- 修改回源 SNI 输入 teek.seasir.top
- 配置缓存过期时间,地址是:/; 类型:目录; 过期时间:0 秒; 权重:1 规则条件:不使用
- 再次添加一个缓存过期时间,地址是:jpg,png,webp,gif; 类型:文件名后缀; 过期时间:7 天; 权重:99 规则条件:不使用
问题总结
对 cnd 的配置不熟悉,导致问题没办法进一步去解决,需要多学习思考。
回源 HOST 未开启;回源 SNI 未配置;缓存策略未限制
配置修复后的完整流程如下:
用户访问 /pages/56b4d5
:CDN 检查缓存,发现根目录 / 的缓存规则为“不缓存”,触发回源。
CDN 回源请求
:携带 HOST 头(加速域名)和 SNI(teek.seasir.top),确保源站正确响应并返回 index.html。
前端路由接管
:浏览器加载 index.html 后,前端路由(如 Vue Router)解析 URL/pages/56b4d5,渲染对应内容。
刷新页面
:流程同上,CDN 始终回源,不再返回缓存的 404 页面。