From 43171597e2aed01eac05b052342dd068b7a6fafb Mon Sep 17 00:00:00 2001 From: laoyang Date: Wed, 23 Sep 2026 07:06:36 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=99=E9=9D=99=E6=80=81=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E5=8A=A0=E7=89=88=E6=9C=AC=E5=8F=B7=EF=BC=8C=E4=BF=AE=E6=8E=89?= =?UTF-8?q?=E3=80=8C=E6=9C=8D=E5=8A=A1=E7=AB=AF=E6=9B=B4=E6=96=B0=E4=BA=86?= =?UTF-8?q?=E4=BD=86=E7=95=8C=E9=9D=A2=E6=B2=A1=E5=8F=98=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现象:CSS 更新并上线后,用户打开站点看不到任何变化,怀疑没部署。 实测服务器上的 style.css 已是新版(与工作树逐字节一致),真实浏览器 直连线上也拿得到新文件,所以问题在客户端缓存: · 页面 HTML 带 no-store,每次都重新渲染 → HTML 一直是新的; · 但 /assets/*.css|js 的响应没有 Cache-Control / Expires,浏览器只好 退回自己的「启发式缓存」——在它自行估算的新鲜期内根本不发请求; · 而 的地址从不改变,文件换了浏览器 也无从得知。于是出现「HTML 新的、CSS 旧的」,界面看起来毫无变化。 修法:新增 asset() 辅助函数,拼上 mtime + 文件大小做 cache busting, 文件名不变而内容一变、地址就变,浏览器只能重新拉取,普通刷新即生效。 版本号同时带上文件大小,挡住「mtime 没变但内容变了」这种漏网情况; 取不到文件信息时不加版本号,退化成原行为,不影响可用性。 已验证:线上 HTML 现在引用 /assets/style.css?v=…;真实浏览器直连线上 三个视口(1920/1280/390)均无横向溢出,资源全部 200;1920px 下顶栏品牌 与正文左边缘同为 420px,头像 26×26(源图 400×400)。 --- src/helpers.php | 23 +++++++++++++++++++++++ templates/layout.php | 7 ++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/helpers.php b/src/helpers.php index 5ec64e0..04b3637 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -25,6 +25,29 @@ function url(string $route, array $params = []): string return '/index.php?' . http_build_query($params); } +/** + * 静态资源地址 + 内容版本号(cache busting)。 + * + * 为什么必须有:CSS/JS 的响应没有 Cache-Control/Expires,浏览器会退回到自己的 + * 「启发式缓存」——在它自行估算的新鲜期内**根本不发请求**。文件换了它也不知道, + * 因为地址一直没变。表现就是「服务端明明更新了,用户看到的还是旧样式」。 + * 拼上随文件变化的版本号后,文件一改地址就变,浏览器只能重新拉。 + * + * 版本号用 mtime + 文件大小:只用 mtime 时,同一秒内改两次会漏; + * 补上大小能挡住绝大多数「内容变了但 mtime 没变」的情况。 + * 取不到文件信息就不加版本号,退化成原来的行为 —— 不影响可用性。 + */ +function asset(string $path): string +{ + $path = '/' . ltrim($path, '/'); + $file = dirname(__DIR__) . $path; + $mtime = @filemtime($file); + if ($mtime === false) { + return $path; + } + return $path . '?v=' . $mtime . '-' . (int)@filesize($file); +} + function redirect(string $route, array $params = [], string $anchor = ''): void { $location = url($route, $params); diff --git a/templates/layout.php b/templates/layout.php index 74d837f..1eed277 100644 --- a/templates/layout.php +++ b/templates/layout.php @@ -15,9 +15,10 @@ $__initial = $__name !== '' ? mb_substr($__name, 0, 1) : '·'; <?= e($pageTitle ?? '家庭出行记录') ?> - - - + + + +