SPA部署到子路径必须配,否则90%静态资源因相对路径解析错误而404;href须以/开头且结尾带/,仅作用于HTML硬编码属性,不影响JS动态请求,且需与Vue Router的base等配置严格一致。

SPA部署到子路径时必须配<base href="/subapp/">
不加这行,90%的静态资源会404。比如HTML在https://example.com/subapp/index.html,但<script src="./assets/index.js"></script>会被浏览器解析成https://example.com/subapp/assets/index.js,而实际构建产物可能发布在根路径/assets/index.js或CDN上。
关键点:
-
href必须以/开头且结尾带/,写成/subapp或subapp/都会被浏览器静默忽略 - 它只修正HTML里硬编码的
src、href、action等属性,不影响JS中fetch('./api')或import() - 必须放在
最前面,早于<title></title>和<meta>,否则部分<link>可能已按原路径解析完毕
<base href="https://cdn.example.com/v2.3/">用于CDN资源统一托管
把所有静态资源(图片、CSS、JS)都指向CDN,避免因部署路径变动导致HTML重写。比如本地开发用http://localhost:3000/,上线后切到https://cdn.example.com/v2.3/,只需改<base>,不用动任何src值。
注意:
立即学习“前端免费学习笔记(深入)”;
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- 绝对URL比根相对路径更稳定,尤其跨域名、跨环境时
- 如果页面本身在
file://协议下打开(如双击HTML文件),href含协议才有效;/subapp/会失效 - CDN路径变更时,务必同步更新
<base>和构建工具的build.base(Vite)或publicPath(Webpack),否则资源加载地址错位
<base target="_blank">批量控制链接与表单行为
想让所有没显式写target的<a></a>、<form></form>都新窗口打开,直接加这一行比逐个加target="_blank"省事。
但风险明显:
-
<form method="POST"></form>提交后跳转到空白页,用户看不到响应,也回不到原页面 - 如果某链接本该由JS拦截(如
router.push()),却因<base target="_blank">强制新开一个#页,控制台报Navigation cancelled -
<iframe src="page.html"></iframe>不受影响,<base target>对<iframe></iframe>无效
为什么Vue Router的base和<base href>必须同时设
两者完全独立:HTML的<base href="/subapp/">只管<script src="index.js"></script>这类资源加载;Vue Router的createRouter({ base: '/subapp/' })只管router.push('/home')跳转逻辑。漏一个就出问题。
典型故障现象:
- 只设
<base href="/subapp/">:JS能加载,但点击<router-link to="/home"></router-link>跳到https://example.com/home(不是/subapp/home) - 只设
router.base:路由跳转正常,但<script src="index.js"></script>请求/index.js,404(实际在/subapp/index.js) - 两个都设但值不一致(如
<base href="/v2/">+router.base = '/subapp/'):跳转和加载路径割裂,调试时Network里看到的请求地址和预期对不上
真正麻烦的不是配置本身,而是Service Worker预缓存、微前端子应用publicPath、甚至CDN缓存键,全都依赖这个前缀的一致性——漏掉一个环节,资源就加载失败。


















