<base>标签重置HTML解析器对后续相对URL的基准起点,必须置于<head>最前且唯一,仅影响其后HTML属性中的纯相对路径,不作用于JS/CSS运行时路径。

<base> 标签不是“加前缀”,而是直接重置 HTML 解析器对后续所有相对 URL 的基准起点——写错一个字符,<img src="logo.png"> 就 404,且浏览器通常不报错,只静默失败。
base href 必须是绝对 URL 或根相对路径(结尾带斜杠)
浏览器只接受 href 值以 https://、http://、// 或 / 开头。其他写法一律被丢弃,不警告也不报错,资源退回到按当前页面 URL 解析。
-
href="assets/"、href="../static/"、href="subapp/"→ 全部无效,<base>形同虚设 -
href="/myapp"→ 结尾缺斜杠,Firefox/Opera 可能截断成/myappcss/,导致style.css拼成/myappcss/style.css -
href="/myapp/"→ ✅ 合法,适用于部署在https://example.com/myapp/的 SPA -
href="https://cdn.example.com/v3/"→ ✅ 推荐,协议、域名、路径明确,不依赖当前页上下文 -
href="//cdn.example.com/v3/"→ ✅ 协议相对,自动继承当前页 http/https
base 必须放在 <head> 最前面,且只能有一个
<base> 影响的是 HTML 解析阶段的顺序逻辑:它只对它之后出现的相对 URL 生效。放错位置或重复声明,等于没写。
- 正确顺序:
<head><base href="/myapp/"><title>App</title><link href="style.css"></head> - 错误示例:
<head><link href="main.css"><base href="/myapp/"></head>→main.css已按原始 URL 解析完毕,不受控 - 放在
<body>里?浏览器直接忽略,不警告也不报错 - 多个
<base>?只有第一个生效;Chrome 控制台会提示Multiple base elements detected. Only the first one is used.
base 只影响 HTML 属性中的纯相对路径,JS/CSS 运行时路径完全不受控
这是最容易误判的一点:<base href="/cdn/"> 不会让 fetch('./api/data.json') 或 import('./utils.js') 自动带上前缀。它只作用于 HTML 解析时的属性值。
立即学习“前端免费学习笔记(深入)”;
- ✅ 真受影响:
<img src="icon.svg">、<script src="bundle.js">、<link href="theme.css">、<form action="submit.php">、CSS 中的background: url(avatar.jpg)(这是唯一穿透到 CSS 的情况) - ❌ 完全不受影响:
fetch('./api/data.json')、import('./utils.js')、new Worker('./worker.js')、CSS 中的@import "reset.css"、<iframe src="/admin/frame.html">(它的src相对于 iframe 当前 URL) - ⚠️ 特别注意:
<img src="/admin/logo.png">这种根相对路径,根本不受<base>控制——它直接拼到当前域名下
SPA 项目中不能只靠 base 标签,前端路由必须显式配 base 参数
<base href="/myapp/"> 不会让 Vue Router 或 React Router v6+ 自动识别子路径;它们完全不读 document.baseURI,必须手动传入 base 配置项。
- Vue Router:
createRouter({ base: '/myapp/' }),否则router.push('/home')会跳到根路径 - React Router v6+:
<Router basename="/myapp">,否则导航和匹配全部错位 - Webpack/Vite 的
publicPath或base配置若和 HTML 中的<base>值重复,会导致资源路径被拼两次(如/myapp//myapp/js/app.js) - 服务端模板或构建工具注入时,要确保
href是已解析的字符串,而非未替换的占位符(如%PUBLIC_URL%或{{ BASE_HREF }}字面量)
最常被忽略的其实是「解析时机」:一旦 HTML 开始解析,<base> 就锁定了;后续任何 JS 插入、修改、重写都无效,连 document.baseURI 返回值都不会变——它只是反射最初那个已解析的值,不是活的代理。



















