给静态资源加版本号,修掉「服务端更新了但界面没变」

现象:CSS 更新并上线后,用户打开站点看不到任何变化,怀疑没部署。
实测服务器上的 style.css 已是新版(与工作树逐字节一致),真实浏览器
直连线上也拿得到新文件,所以问题在客户端缓存:

  · 页面 HTML 带 no-store,每次都重新渲染 → HTML 一直是新的;
  · 但 /assets/*.css|js 的响应没有 Cache-Control / Expires,浏览器只好
    退回自己的「启发式缓存」——在它自行估算的新鲜期内根本不发请求;
  · 而 <link href="/assets/style.css"> 的地址从不改变,文件换了浏览器
    也无从得知。于是出现「HTML 新的、CSS 旧的」,界面看起来毫无变化。

修法:新增 asset() 辅助函数,拼上 mtime + 文件大小做 cache busting,
文件名不变而内容一变、地址就变,浏览器只能重新拉取,普通刷新即生效。
版本号同时带上文件大小,挡住「mtime 没变但内容变了」这种漏网情况;
取不到文件信息时不加版本号,退化成原行为,不影响可用性。

已验证:线上 HTML 现在引用 /assets/style.css?v=…;真实浏览器直连线上
三个视口(1920/1280/390)均无横向溢出,资源全部 200;1920px 下顶栏品牌
与正文左边缘同为 420px,头像 26×26(源图 400×400)。
This commit is contained in:
2026-09-23 07:06:36 +08:00
parent a43dd06d1f
commit 43171597e2
2 changed files with 27 additions and 3 deletions
+4 -3
View File
@@ -15,9 +15,10 @@ $__initial = $__name !== '' ? mb_substr($__name, 0, 1) : '·';
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title><?= e($pageTitle ?? '家庭出行记录') ?></title>
<link rel="stylesheet" href="/assets/style.css">
<link rel="stylesheet" href="/assets/vendor/cropper/cropper.min.css">
<script src="/assets/vendor/cropper/cropper.min.js"></script>
<?php /* 静态资源一律走 asset():不带版本号的话,浏览器会一直用缓存里的旧 CSS */ ?>
<link rel="stylesheet" href="<?= e(asset('assets/style.css')) ?>">
<link rel="stylesheet" href="<?= e(asset('assets/vendor/cropper/cropper.min.css')) ?>">
<script src="<?= e(asset('assets/vendor/cropper/cropper.min.js')) ?>"></script>
<script>
window._AMapSecurityConfig = {
securityJsCode: '<?= e(app_config()['amap']['security_js'] ?? '') ?>',