base标签仅影响html解析时相对路径的拼接起点,不改变缓存机制;但base错配会导致请求路径错误,使http缓存失效,且html自身必须禁用长期缓存以确保base更新生效。

base 标签本身不改变浏览器缓存行为
<base> 只影响 HTML 解析时相对路径的拼接起点,它不修改资源 URL 字符串本身,也不干预 HTTP 缓存头、ETag 或 Cache-Control 的生效逻辑。一个 <script src="app.js"></script> 在加了 <base href="/sub/"> 后,实际请求的是 /sub/app.js,但该请求是否命中强缓存、是否走协商缓存,完全取决于服务端对该路径返回的响应头——和 base 无关。
但 base 错配会导致缓存“错位”失效
当 <base href="/sub/"> 和实际部署路径不一致时,浏览器会向错误路径发起请求,而那个路径大概率返回 404 或旧资源,结果就是:明明服务端已更新 JS 文件并设置了 Cache-Control: public, max-age=31536000,用户却始终加载不到新版本,因为请求压根没打到正确的 URL 上。
-
<base href="/sub/">但服务端静态资源实际放在/assets/→ 请求/sub/app.js404,浏览器不会 fallback 到/assets/app.js - Webpack 的
publicPath: '/sub/'和 HTML 中手写<base href="/sub/">同时存在 → 资源路径被拼两次,如/sub//sub/app.js,服务端无此路径,缓存策略再合理也无效 - Vite 已设
build.base: '/sub/',又在 HTML 里手动加<base href="/sub/">→ 构建产物路径和运行时解析路径重复叠加,Service Worker 预缓存的/sub/app.js和真实请求的/sub//sub/app.js对不上
HTML 模板必须禁用长期缓存,否则 base 变更永远不生效
如果 HTML 文件本身被 CDN 或 Nginx 缓存了 1 年(Cache-Control: public, max-age=31536000),那么你改了 <base href="/newpath/"> 并重新部署,99% 的用户仍加载旧 HTML,继续按 /oldpath/ 请求资源——所有后续缓存策略都建立在错误 base 基础上。
- HTML 必须设为
Cache-Control: no-cache, must-revalidate或max-age=0 -
meta http-equiv="Cache-Control"在现代浏览器中无效,别依赖它 - 哪怕用了文件名哈希(如
index.a1b2c3.html),只要它是 SPA 入口页,就不能长期缓存——路由、base、JS 加载路径全靠它驱动
data: URL 和 base 标签共存时缓存逻辑割裂
<img src="data:image/png;base64,..."> 完全绕过 <base>,也不参与 HTTP 缓存。它直接解码渲染,每次加载都走完整流程,无法利用强缓存或协商缓存。当页面中混用 <base> 管理外链资源 + 大量内联 data: 图片时,会出现缓存策略不统一:
- 外链 CSS/JS 能长期缓存,data: 图片每次重绘都重新 decode,拖慢渲染
- CDN 缓存策略对 data: 内容无效,压缩、版本管理、边缘预热全部落空
- 调试时发现图片加载慢,容易误判为 base 配置问题,实际是 data: 自身性能瓶颈
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











