base href值错误会导致相对路径静默回退到当前页面URL:仅以http://、https://、//或/开头才生效,必须置于head最顶部且唯一,不影响fetch/import等运行时路径,SPA需避免与构建配置重复。

base href 值写错会导致所有相对路径静默回退到当前页面 URL
浏览器对 <base> 的校验极其严格:只要 href 值不以 http://、https://、// 或 / 开头,整条标签就被直接丢弃——控制台无报错、Network 面板里请求看起来“正常”,但实际全部按当前页面 URL 解析,上线后批量 404。
常见无效写法包括:
-
href="assets/"(缺协议和根斜杠) -
href="../static/"(含..,规范禁止) -
href="/myapp(结尾没斜杠,Firefox 会截断成/myappcss/) -
href="%PUBLIC_URL%/"(构建未替换时就是字面量字符串)
真正安全的只有两种形式:href="https://cdn.example.com/v3/"(绝对 URL,推荐 CDN 场景),或 href="/myapp/"(根相对路径,开头和结尾都必须是 /)。
base 标签必须放在 <head> 最顶部且只能有一个
<base> 只影响它之后出现的 HTML 相对路径,且仅在解析阶段生效。放错位置等于没写。
立即学习“前端免费学习笔记(深入)”;
典型错误场景:
-
<head><title>App</title><base href="/app/"></head>→<title>不受影响,更关键的是,如果前面已有<link href="main.css">,那它早已按原始页面 URL 解析完毕 -
<body><base href="/app/"></body>→ 浏览器直接忽略,无任何提示 - SSR 模板拼接或 Vue/React 组件内动态插入多个
<base>→ 只有第一个生效,Chrome 控制台会提示Multiple base elements detected. Only the first one is used.
正确顺序必须是:<head><base href="/myapp/"><title></title><link href="style.css"><script src="app.js"></head>。
base 不影响 fetch、import、@import 等运行时路径
这是最容易误判的一点:<base href="/cdn/"> 不会让 fetch('./api/user') 或 import('./utils.js') 自动带上前缀。它只作用于 HTML 解析时硬编码的纯相对路径。
真正受影响的属性包括:
<img src="icon.png"><script src="app.js"><link href="style.css"><a href="about.html">- CSS 文件中
background: url(avatar.jpg)(注意:这是 HTML 解析时计算的,不是 CSS 引擎自己 resolve)
完全不受影响的包括:
-
fetch('./api/user')、import('./utils.js') -
@import "reset.css"、new Worker('./worker.js') -
<iframe src="/admin/frame.html">(根相对路径,直接拼域名) -
<img srcset="logo-2x.png 2x">(srcset不走base规则)
SPA 部署子路径时,base 与路由/构建配置不可共存
Vue Router 和 React Router v6+ 完全不读 document.baseURI,必须显式传入 base 或 basename 配置;否则 router.push('/home') 会跳到根路径而非子路径,造成白屏或导航错位。
同时,构建工具配置与 <base> 易发生重复拼接:
- Webpack 的
publicPath和手写的<base href="/myapp/">若值相同,资源路径可能被拼两次,如/myapp//myapp/js/app.js - Vite 已设
build.base = "/myapp/",HTML 中再手动加<base>→ 风险叠加
更稳妥的做法是二选一:
— 仅用构建工具统一控制(如 Vite 设 build.base,HTML 中不写 <base>);
— 或仅用 <base> 控制静态资源,构建工具设 publicPath: ""(空字符串),避免叠加。



















