base 基准 URL
<base> 元素用于为文档中的所有相对 URL 指定一个基准地址,同时可以设置链接的默认打开方式。它是 <head> 中一个功能强大但使用场景相对较少的标签。
前置知识
阅读本节前,建议先了解:meta 其他属性
基础概念
base 的作用
<base> 元素解决了一个问题:当页面中大量使用相对 URL 时,<base> 可以统一设置这些相对 URL 的基准路径,而不需要每个 URL 都写完整的绝对路径。
它有两个核心功能:
- 设置基准 URL(href):所有相对 URL 都会基于这个基准进行解析
- 设置默认打开方式(target):所有
<a>标签默认的打开方式
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>base 标签示例</title>
<base href="https://example.com/app/" target="_blank">
</head>
<body>
<!-- 这些链接都会解析为 https://example.com/app/ 下的路径 -->
<a href="home">首页</a> <!-- → https://example.com/app/home -->
<a href="about">关于</a> <!-- → https://example.com/app/about -->
<img src="logo.png" alt="Logo"> <!-- → https://example.com/app/logo.png -->
<!-- 所有链接都会在新窗口打开(因为 target="_blank") -->
</body>
</html>一个文档只能有一个 base
这是 <base> 标签最重要的限制:一个 HTML 文档中最多只能有一个 <base> 元素。如果出现多个,只有第一个会生效,后续的都会被忽略。
<!-- 错误!多个 base 标签,只有第一个生效 -->
<head>
<base href="https://example.com/">
<base href="https://other.com/"> <!-- 被忽略 -->
</head>语法
基本语法
<base href="https://example.com/">
<base target="_blank">
<base href="https://example.com/" target="_blank">属性说明
| 属性 | 值 | 说明 |
|---|---|---|
href | URL | 基准 URL,必须是绝对路径 |
target | _self / _blank / _parent / _top | 默认的链接打开方式 |
href 属性
<!-- 设置基准 URL -->
<base href="https://example.com/app/">
<base href="https://cdn.example.com/static/">
<base href="/base-path/">- 值必须是绝对 URL(以协议开头)或以
/开头的绝对路径 - 末尾的斜杠
/很重要,它决定了路径的解析方式 <base href>必须在文档中有使用相对 URL 的元素之前出现
href 末尾的斜杠至关重要
<!-- 有末尾斜杠:相对路径解析为子目录 -->
<base href="https://example.com/app/">
<a href="page"> → https://example.com/app/page
<!-- 没有末尾斜杠:相对路径解析为同级 -->
<base href="https://example.com/app">
<a href="page"> → https://example.com/page(注意:app 被替换掉了!)target 属性
| 值 | 说明 |
|---|---|
_self(默认) | 在当前窗口/标签页中打开 |
_blank | 在新的窗口/标签页中打开 |
_parent | 在父框架中打开 |
_top | 在最顶层窗口中打开 |
详细说明
base 对各种 URL 的影响
<base> 标签会影响文档中以下元素的相对 URL 解析:
| 元素/属性 | 是否受 base 影响 |
|---|---|
<a href=""> | 是 |
<img src=""> | 是 |
<link href=""> | 是 |
<script src=""> | 是 |
<form action=""> | 是 |
<iframe src=""> | 是 |
<source src=""> | 是 |
CSS 中的 url() | 否 |
<style> 中的 @import | 否 |
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<base href="https://cdn.example.com/static/">
<link rel="stylesheet" href="css/style.css">
<!-- 实际 URL: https://cdn.example.com/static/css/style.css -->
<script src="js/app.js" defer></script>
<!-- 实际 URL: https://cdn.example.com/static/js/app.js -->
</head>
<body>
<img src="images/logo.png" alt="Logo">
<!-- 实际 URL: https://cdn.example.com/static/images/logo.png -->
<a href="about.html">关于我们</a>
<!-- 实际 URL: https://cdn.example.com/static/about.html -->
<form action="/api/submit" method="post">
<!-- action 使用绝对路径,不受 base 影响 -->
<!-- 实际 URL: https://cdn.example.com/api/submit(基于 base 的域名) -->
</form>
</body>
</html>base href 会覆盖 form action 的行为
如果 <base href="https://cdn.example.com/static/">,那么 <form action="/api/submit"> 实际提交的 URL 是 https://cdn.example.com/api/submit,而不是你期望的服务器域名。这是一个非常容易出错的地方!
URL 解析规则
当设置了 <base href="https://example.com/app/v2/"> 后:
| 相对 URL | 解析结果 | 说明 |
|---|---|---|
page.html | https://example.com/app/v2/page.html | 相对于 base 路径 |
./page.html | https://example.com/app/v2/page.html | 同上 |
../page.html | https://example.com/app/page.html | 上一级目录 |
/page.html | https://example.com/page.html | 网站根路径 |
//other.com/page | https://other.com/page | 协议相对 URL |
https://other.com/page | https://other.com/page | 绝对 URL,不受 base 影响 |
base 与 <head> 中其他标签的关系
<base> 标签会影响 <head> 中其他使用相对 URL 的标签,因此它应该在这些标签之前声明:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- base 应该在 link 和 script 之前 -->
<base href="https://cdn.example.com/static/">
<!-- 受 base 影响 -->
<link rel="stylesheet" href="css/style.css">
<link rel="icon" href="favicon.ico">
<script src="js/app.js" defer></script>
</head>实战示例
静态资源 CDN 加速
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CDN 资源加载</title>
<!-- 所有静态资源从 CDN 加载 -->
<base href="https://cdn.example.com/static/">
<link rel="stylesheet" href="css/style.css">
<script src="js/app.js" defer></script>
</head>
<body>
<!-- 注意:图片也从 CDN 加载 -->
<img src="images/banner.jpg" alt="Banner">
<!-- 如果需要链接到主站,必须使用绝对 URL -->
<a href="https://www.example.com/about">关于我们</a>
<!-- 或者使用协议相对 URL -->
<a href="//www.example.com/about">关于我们</a>
</body>
</html>新窗口打开所有链接
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>外部链接列表</title>
<!-- 所有链接默认在新窗口打开 -->
<base target="_blank">
<style>
body {
font-family: system-ui, sans-serif;
max-width: 600px;
margin: 40px auto;
padding: 0 20px;
}
a {
display: block;
padding: 10px;
border-bottom: 1px solid #eee;
color: #0066cc;
text-decoration: none;
}
a:hover { text-decoration: underline; }
</style>
</head>
<body>
<h1>友情链接</h1>
<!-- 所有链接都会在新窗口打开,无需逐个添加 target="_blank" -->
<a href="https://developer.mozilla.org">MDN Web Docs</a>
<a href="https://github.com">GitHub</a>
<a href="https://stackoverflow.com">Stack Overflow</a>
<!-- 如果某个链接需要在本窗口打开,可以单独覆盖 -->
<a href="/home" target="_self">返回首页(本窗口打开)</a>
</body>
</html>GitHub Pages / 单页应用的 base 配置
在使用 Vue CLI、Vite 等构建工具时,如果项目部署在子路径下,构建工具会自动在 HTML 中注入 <base> 标签:
<!-- Vite 构建的页面,部署在 https://example.com/my-app/ -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<!-- Vite 自动注入 base 路径 -->
<base href="/my-app/">
<link rel="stylesheet" href="assets/style.css">
</head>
<body>
<div id="app"></div>
<script type="module" src="/my-app/assets/app.js"></script>
</body>
</html>使用 JavaScript 读取 base 信息
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>读取 base 信息</title>
<base href="https://example.com/app/" target="_blank">
<style>
body {
font-family: system-ui, sans-serif;
max-width: 600px;
margin: 40px auto;
padding: 0 20px;
}
.info {
background: #f5f5f5;
padding: 15px;
border-radius: 4px;
font-family: monospace;
white-space: pre-line;
margin: 15px 0;
}
a {
color: #0066cc;
}
</style>
</head>
<body>
<h1>Base 标签信息</h1>
<div class="info" id="output"></div>
<p>测试链接: <a href="test-page">相对链接</a></p>
<script>
var base = document.querySelector('base');
var output = document.getElementById('output');
if (base) {
output.textContent =
'base.href: ' + base.href + '\n' +
'base.target: ' + base.target + '\n\n' +
'document.baseURI: ' + document.baseURI;
} else {
output.textContent = '未找到 base 标签。';
}
// 查看链接的实际解析 URL
var link = document.querySelector('a');
console.log('链接的 href:', link.href);
console.log('链接的 target:', link.target);
</script>
</body>
</html>注意事项
1. form action 的陷阱
<base href> 会影响 <form action=""> 的 URL 解析,这可能导致表单提交到错误的地址:
<base href="https://cdn.example.com/static/">
<!-- 错误!表单会提交到 CDN 域名 -->
<form action="/api/login" method="post">
<!-- 实际提交到: https://cdn.example.com/api/login -->
<!-- 而不是: https://www.example.com/api/login -->
</form>
<!-- 正确:使用绝对 URL -->
<form action="https://www.example.com/api/login" method="post">
<!-- 实际提交到: https://www.example.com/api/login -->
</form>2. SVG 中的相对 URL 也受影响
如果页面中包含内联 SVG,SVG 中的 xlink:href 也会受到 <base> 的影响。
3. JavaScript 中的相对路径不受影响
JavaScript 代码中的相对路径(如 fetch('api/data'))不受 <base> 影响,它们相对于当前页面 URL 解析。
<base href="https://cdn.example.com/static/">
<script>
// fetch 的 URL 相对于当前页面,不是 base
fetch('/api/data')
.then(function(res) { return res.json(); })
.then(function(data) { console.log(data); });
</script>4. 锚点链接的行为
<base href> 会影响锚点链接的解析方式:
<base href="https://example.com/app/">
<!-- 这个链接会导航到 https://example.com/app/#section -->
<a href="#section">跳转到章节</a>最佳实践
1. 谨慎使用 base 标签
<base> 标签的全局影响性意味着它很容易带来意外的副作用。如果可以用其他方式解决(如在构建工具中配置 publicPath),就不要使用 <base>。
2. 确保 href 末尾有斜杠
<!-- 推荐 -->
<base href="https://example.com/app/">
<!-- 危险!没有斜杠 -->
<!-- <base href="https://example.com/app"> -->3. 使用 target="_blank" 时注意安全性
<!-- 如果设置了 base target="_blank",所有链接都会在新窗口打开 -->
<base target="_blank">
<!-- 出于安全考虑,外部链接建议加上 rel="noopener noreferrer" -->
<a href="https://example.com" rel="noopener noreferrer">外部链接</a>4. 在构建工具中处理 base 路径
现代前端框架通常通过构建配置来处理公共路径:
// Vite 配置
export default {
base: '/my-app/'
}
// Vue CLI 配置
module.exports = {
publicPath: '/my-app/'
}
// Webpack 配置
module.exports = {
output: {
publicPath: '/my-app/'
}
}5. 不推荐同时使用 base href 和 base target
<!-- 不推荐:同时设置 href 和 target,增加了复杂度 -->
<base href="https://cdn.example.com/static/" target="_blank">
<!-- 推荐:只设置其中一个,或都不设置 -->base 速查表
| 项目 | 说明 |
|---|---|
| 语法 | <base href="URL"> 或 <base target="值"> |
| 位置 | <head> 中,在需要解析相对 URL 的元素之前 |
| 数量限制 | 每个文档最多一个 |
| href | 必须是绝对 URL 或以 / 开头的路径 |
| target | _self、_blank、_parent、_top |
| 影响 | a、img、link、script、form、iframe 等的相对 URL |
| 不影响 | CSS url()、JavaScript 中的路径 |
下一节
继续学习:link 标签