base href 值非法导致 router.push() 跳转到根路径,是因为浏览器静默丢弃非法 标签(如 assets/、/myapp),仅接受以 / 或协议开头且结尾带 / 的合法值;vue router 与 react router 的 base 配置与此无关,需显式设置;锚点跳转 href="#section2" 会因 触发页面重载;构建工具 publicpath 与 混用将导致双斜杠 404。

base href 值非法导致 router.push() 跳转到根路径
不是路由框架出错,而是 <base> 标签没生效,但你误以为它在起作用。浏览器对 href 值校验极严:只要不是以 /、http://、https:// 或 // 开头,整条标签就被静默丢弃——控制台无提示,但 router.push('/home') 仍按默认行为跳到 https://example.com/home,而非预期的子路径。
常见非法写法:assets/、../static/、/myapp(结尾缺 /)、%PUBLIC_URL%/(未被构建替换时就是字面量)。这些都会让 <base> 形同虚设。
- 检查方式:打开 DevTools → Elements → 确认
<base href="/myapp/">是否位于最顶部,且值以/开头、以/结尾 - 合法值只有两种:
/myapp/(根相对,必须双斜杠)或https://cdn.example.com/myapp/(绝对 URL) - Firefox/Opera 对结尾斜杠更敏感:
/myapp可能导致css/app.css被拼成/myappcss/app.css
Vue Router / React Router v6+ 的 base 配置与 完全无关
<base href="/myapp/"> 不会影响 createRouter() 或 <router basename></router> 的行为。前端路由完全不读 document.baseURI,它们是两套独立机制。漏配或错配就会出现“资源加载走 /myapp/js/app.js,点击链接却跳到 /home”这种割裂现象。
- Vue Router 必须显式传入:
createRouter({ history: createWebHistory('/myapp/'), base: '/myapp/' })(base参数在 v4.1+ 后为必需) - React Router v6+ 必须用
<router basename="/myapp"></router>包裹应用,注意这里不用结尾斜杠 - 值必须字面量一致:
/myapp/≠/myapp≠/myapp//,大小写和末尾斜杠都参与匹配
锚点跳转 href="#section2" 触发页面重载
这是最隐蔽的问题:<base href="/myapp/"> 会让浏览器把 href="#section2" 解析为相对路径,拼成 /myapp/#section2。这个 URL 和当前页(比如 /myapp/page)路径不同,触发完整导航,页面刷新、滚动重置、SPA 路由不响应。
- Network 面板能看到一次对
/myapp/的空 HTML 请求(状态码 200),这就是重载证据 - 不要删
<base>,而应改写链接:href={window.location.pathname + "#section2"}(React)或href="${location.pathname}#section2"(服务端渲染) - 更稳妥方案:用
new URL("#section2", document.baseURI).href动态生成,它会正确忽略<base>对 hash 的干扰 - 首次加载带 hash(如
/myapp/page#faq)时,需手动调用document.getElementById("faq")?.scrollIntoView(),因为路由初始化可能早于 DOM 渲染
构建工具 publicPath / base 与 混用引发双斜杠 404
Vite 的 build.base 或 Webpack 的 publicPath 若与 HTML 中的 <base href="/myapp/"> 值重复,会导致资源路径被拼接两次,例如 /myapp//myapp/js/app.js,最终 404。
- 推荐策略二选一:只用构建工具统一控制(如 Vite 设
build.base = "/myapp/",HTML 中不写<base>),或仅用<base>控制静态资源(构建工具设publicPath: "") - 微前端场景下尤其危险:
<base>是全局生效的,子应用若也写自己的<base>,会覆盖父应用的,导致 chunk 加载中断 -
fetch('./api')、import('./utils')、@import "reset.css"全都不受<base>影响,别指望它统一重写运行时路径
真正容易被忽略的点是:所有问题都静默发生——没有控制台报错、没有警告、甚至 Network 请求看起来“正常”。排查必须从 <base> 的合法性开始,逐层确认它是否真的在起作用,而不是直接怀疑路由或构建配置。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











