base href必须是绝对URL或根相对路径(以/开头且结尾带斜杠),否则浏览器静默忽略;须置于<head>最前且唯一;仅影响HTML属性中纯相对路径(如src="logo.png"),不影响fetch、import等JS路径及CSS@import。

base href 必须是绝对 URL 或根相对路径,否则静默失效
浏览器只认以 http://、https://、// 或 / 开头的 href 值。其他写法——比如 static/、../assets、https://example.com(结尾没 /)——整条 <base> 都被丢弃,不报错、不警告,但所有 src、href 仍按当前页面 URL 解析,404 风险陡增。
正确写法只有两类:
-
<base href="https://cdn.example.com/v2.3/">(推荐,明确、跨环境稳定) -
<base href="/app/">(根相对,部署到不同子路径时必须同步改)
特别注意:Firefox 和 Opera 对结尾缺 / 的 URL 会截断拼接,比如 https://example.com + css/app.css 可能变成 https://example.comcss/app.css。
哪些资源受 base 影响,哪些完全不受
<base> 只在 HTML 解析阶段起作用,仅重写硬编码在标签属性里的纯相对路径(即不以 /、: 或协议开头的值)。
立即学习“前端免费学习笔记(深入)”;
✅ 明确受影响:
<img src="logo.png"><link href="style.css"><script src="index.js"><form action="login.php">- CSS 中的
background: url(avatar.jpg)
❌ 完全不受影响:
fetch('./api/user')import('./utils.js')new Worker('./worker.js')- CSS
@import "reset.css" -
<iframe src="page.html">(注意:src是动态加载,不走 base)
⚠️ 半受影响:document.baseURI 返回 <base href> 的值,可用于 new URL('data.json', document.baseURI);但 window.location 和 document.URL 不变。
SPA 部署子路径时,base 标签和前端路由必须配对设置
Vue Router 的 base: '/subpath/' 和 HTML 中的 <base href="/subpath/"> 是两套独立机制,缺一不可:
- 只设
<base href="/subpath/">:JS chunk 能加载,但router.push('/home')会跳到/home(根路径),不是/subpath/home - 只设 Vue Router
base:路由跳转正常,但<script src="index.js">请求的是/index.js,实际文件在/subpath/index.js,404 - Vite 构建若已设
build.base: '/subpath/',HTML 中就不该再手动写<base href="/subpath/">,否则路径重复拼接成/subpath//subpath/js/app.js
微前端场景下还要小心 Webpack 的 publicPath,三者值相同会导致路径叠加,比如 /subpath/subpath/js/app.js。
target 属性会影响 form 和 iframe,不只是 a 标签
<base target="_blank"> 不只是让链接新窗口打开,它会全局覆盖所有未显式声明 target 的交互行为:
-
<form method="POST">提交后跳转到新页(用户看不到响应,也回不到原页面) -
<iframe src="embed.html">加载也受约束,哪怕没写target - 如果
target="myframe"但页面没有<iframe name="myframe">,行为退化为_self
最易踩坑的是 JS 拦截表单提交的场景:写了 <base target="_blank"> 后,event.preventDefault() 失效,空白页打开一个 #,控制台报错。
真正麻烦的从来不是配置本身,而是构建产物、CDN 缓存、Service Worker 预缓存路径全部依赖这个前缀的一致性——漏掉一个环节,就出现资源加载失败或路由白屏。



















