base标签强制重写所有静态相对URL解析,仅作用于HTML硬编码的src/href/action等属性,对JS动态创建资源、CSS背景图、fetch/import等运行时行为无效。
它不是“建议”浏览器怎么解析路径,而是直接接管——只要页面里写了 <base href="https://example.com/app/">,那么所有 <img src="logo.png">、<link href="style.css">、<a href="about.html"> 都会被当作相对于 https://example.com/app/ 来拼接,和当前页面实际 URL 完全无关。
这意味着:你打开的是 https://example.com/app/sub/page.html,但 src="logo.png" 最终请求的地址是 https://example.com/app/logo.png,而不是你直觉认为的 https://example.com/app/sub/logo.png。
以下写法全部非法,浏览器会静默忽略 <base> 或导致不可预测行为:
<base href="../assets/">(含 ..)<base href="static/">(无协议无域名)<base href="//cdn.example.com/">(协议相对 URL,在部分旧环境不稳)正确写法只有两种:
立即学习“前端免费学习笔记(深入)”;
<base href="https://example.com/app/">(推荐,明确可控)<base href="/app/">(根相对,依赖当前域名,部署到子目录时需同步调整)<base target="_blank"> 不只让链接新窗口打开,还会让 <form> 提交后跳转到新页、<iframe> 的 src 加载也受其影响——哪怕你没显式写 target 属性。
常见陷阱:
<base target="_blank">,但某个 <a href="#"> 本意是 JS 拦截,结果空白页打开一个 #,控制台报错<form method="POST"> 被强制新窗口提交,用户看不到响应,也回不到原页面target 值若为自定义名字(如 "myframe"),但页面没对应 <iframe name="myframe">,行为退化为 _self
<base> 只作用于 HTML 解析阶段的静态属性:即 src、href、action 等硬编码在标签上的值。它对运行时行为完全无效:
document.createElement('img').src = 'logo.png' → 按当前页面 URL 解析element.style.backgroundImage = "url(bg.jpg)" → 不走 <base>,按 CSS 规则解析(相对 CSS 文件位置)import('./module.js') 或 fetch('./data.json') → 全部无视 <base>,按 JS 执行上下文解析这点最容易被忽略:你以为加了 <base> 就一劳永逸,结果动态加载的图片 404,接口 404,连 @import 的 CSS 也 404——因为它们根本不在 <base> 的管辖范围内。