base target="_blank" 会无差别影响所有未显式声明target的可跳转元素(如a、form、iframe),导致锚点跳转、表单提交等异常,并因不自动添加rel="noopener noreferrer"而存在安全风险。

base target="_blank" 确实会影响所有没写 target 的 a 标签
但它不是“只影响 a”,而是无差别作用于所有未显式声明 target 的可跳转元素,包括 form、iframe(当用 name 配合 target 时),甚至部分 JS 触发的导航(如 location.href 不受影响,但 <a href="javascript:..."> 会受波及)。
常见错误现象:
- 加了
<base target="_blank">后,原本用href="#section"跳转页面内锚点的链接,突然在新标签页打开一个空白页 -
<form method="post">提交后整个表单响应被载入新标签页,用户看不到成功提示,也回不到原页面 - 页面里有
<iframe name="sidebar">,但你写了<base target="sidebar">却没配href,结果所有链接都试图往这个 iframe 里加载,失败后退化为_self
为什么 base 不自动加 rel="noopener noreferrer"
浏览器规范明确:<base> 只控制 target,不干涉 rel。这意味着所有由它触发的新标签页,都能通过 window.opener 反向访问原页面——攻击者可能借此执行重定向、窃取 sessionStorage 或注入脚本。
必须手动防护:
立即学习“前端免费学习笔记(深入)”;
- 如果坚持用
<base target="_blank">,就得在每个实际生效的<a>上补rel="noopener noreferrer"(<base>不帮你干这事) - 更稳妥的做法是放弃
<base>,改用 JS 批量处理:document.querySelectorAll('a:not([target])').forEach(a => { a.rel = 'noopener noreferrer'; a.target = '_blank'; }); - 注意:JS 注入时机要早于用户点击,建议放在
<head>末尾或DOMContentLoaded回调中
base 的作用范围其实很窄:只管静态 HTML 属性
它只解析文档加载时已写死在 HTML 中的 href、src、action 值,对运行时动态生成的内容完全无效。
典型场景差异:
-
<a href="/about">→ 受<base target="_blank">影响 -
<a href="javascript:void(0)" onclick="goTo('/about')">→ 不受影响(跳转由 JS 控制) -
const a = document.createElement('a'); a.href = '/contact'; document.body.appendChild(a);→ 不受影响(DOM 插入发生在解析之后) -
<img src="logo.png">→src是资源请求,不涉及target,所以不受影响
真正安全又可控的统一方案其实是 CSS + JS 组合
纯 HTML 的 <base> 太粗暴,容易漏测边界行为。现代项目更推荐分层控制:
- 用 CSS 选择器定位目标链接:
a[href^="http"]:not([href^="https://yoursite.com"])(外部链接) - 用 JS 统一绑定行为:
a.setAttribute('target', '_blank'); a.rel = 'noopener noreferrer'; - 对内部相对链接(如
/help、#faq)明确排除,避免误伤 - 若需服务端渲染统一处理,可在模板层加条件判断,比客户端 JS 更早介入
最容易被忽略的一点:锚点链接(href="#...")和空链接(href="#")在 <base target="_blank"> 下也会新开空白页——这不是 bug,是规范行为,但几乎没人想要它。



















