标签不触发缓存,但路径写错会导致资源加载错位,旧缓存反而掩盖真实错误;其值必须以http://、https://、//或/开头且结尾带/,否则静默失效;与构建工具publicpath或service worker缓存路径不一致时,会引发404、样式失效等隐蔽问题。

<base> 标签本身不触发缓存,但它改写了资源路径的解析起点——一旦路径拼错,浏览器就去错地方找文件,而那个“错地方”如果恰好有旧缓存,就会静默加载陈旧资源,造成样式失效、脚本 404、API 路径偏移等表象。这不是缓存策略问题,是路径错位后缓存“帮倒忙”。
base href 写错导致资源加载路径错位,缓存反而掩盖问题
浏览器对 <base href="..."> 的校验极严:值不是以 http://、https://、// 或 / 开头,整条标签就被丢弃,且不报错、不警告。常见无效写法:
-
href="assets/"→ 静默失效,<script src="app.js"></script>仍按当前页面 URL 拼接,上线后批量 404 -
href="../static/"→ 含..,不被识别,等同于没写 -
href="/myapp"(结尾缺/)→ Firefox/Opera 会截断为/myappcss/app.css,直接 404
此时若旧资源还在缓存里,浏览器就继续用它,让你误以为“改了 base 没生效”,其实是根本没生效,还被缓存挡住了真实错误。
本地开发时 base 与后端路由冲突,缓存让跳转更诡异
本地开发常用 http://localhost:3000/,但有人写 <base href="/">,结果:
-
<img src="logo.png">加载http://localhost:3000/logo.png(正确) -
<a href="about"></a>点击跳转到http://localhost:3000/about(而非预期的http://localhost:3000/下的 SPA 子路由) - 若后端没配通配路由,返回 404 HTML;而该 HTML 又被缓存,下次刷新直接显示旧 404 页
推荐写法:<base href="http://localhost:3000/">(绝对 URL,结尾带 /),避免和后端路由逻辑打架。
构建工具 publicPath 和手写 base 混用,缓存放大双斜杠错误
Webpack 设了 publicPath: "/admin/",Vite 设了 build.base: "/admin/",你又在 HTML 里手动加 <base href="/admin/">,三者叠加会导致:
- 预期请求:
/admin/js/app.js - 实际请求:
/admin//admin/js/app.js(中间两个//) - 服务器返回 404,但浏览器可能缓存了之前成功的响应(比如从 /js/app.js 加载过),于是“有时好有时坏”
Vite 构建时已设 base,HTML 中就不该再写 <base>;Webpack 项目若用 HtmlWebpackPlugin 插件注入 <base>,确保其值与 publicPath 完全一致,且只出现一次。
Service Worker 缓存路径依赖 base,但 base 不生效时预缓存就错位
Service Worker 脚本中常这样写预缓存列表:
const CACHE_NAME = 'my-app-v1'; const urlsToCache = [ self.location.origin + '/admin/style.css', self.location.origin + '/admin/app.js' ];
但如果 HTML 里漏了 <base href="/admin/">,而你又期望所有相对路径都基于 /admin/ 解析,那么:
-
<link href="style.css">实际加载的是/style.css(非/admin/style.css) - Service Worker 却缓存了
/admin/style.css,导致后续 fetch 命中缓存但内容不匹配 - 这种错位不会报错,只会表现为“样式突然失效”或“JS 执行一半中断”
真正关键点:base 标签只影响 HTML 解析阶段的纯相对路径,而 Service Worker 的缓存路径是运行时拼的——两者必须靠人工对齐,浏览器不会帮你自动桥接。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











