是,base target 会强制覆盖未显式声明 target 的 form 元素的默认跳转行为,只要 form 未设 target 属性,就无条件继承 base target 值;其优先级高于隐式 _self,但低于 form 自身的 target 或 button 的 formtarget 属性。

base target 会强制覆盖 form 的默认跳转行为
<base target> 不是“建议”,而是硬性默认值。只要 <form></form> 没写自己的 target 属性,它就会无条件继承 <base target> 的值——哪怕你只在页面顶部加了一行 <base target="_blank">,所有没显式声明 target 的表单提交都会跳到新标签页。
常见误判是以为“表单没写 target 就该留在当前页”,其实不是:HTML 规范明确要求,<base> 的 target 对 <form></form> 和 <a></a> 一视同仁,且优先级高于隐式默认(即 _self)。
- 表单写了
target="_self"→ 覆盖<base>,留在当前页 - 表单写了
target="_top"→ 覆盖<base>,强制顶层跳转 - 表单完全没写
target→ 直接按<base target>执行,哪怕你只想让它刷新当前页
form 的 target 属性优先级永远高于 base target
<form></form> 自己的 target 是最终决定者,<base> 只是兜底。这个优先级关系不会因位置、顺序或 JS 操作改变——哪怕你在 JS 里先设了 document.querySelector('form').target = '_blank',再插入 <base target="_self">,表单仍走 _blank。
特别注意 formtarget 属性:它只作用于 type="submit" 的按钮或输入框,且优先级比 <form></form> 的 target 还高。也就是说:
-
<form target="_self"><button formtarget="_blank">提交</button></form>→ 点这个按钮,走_blank -
<form target="_self"><button>提交</button></form>→ 没formtarget,走_self -
<form><button formtarget="_blank">提交</button></form>→<form></form>没target,但按钮有formtarget,仍走_blank
SPA 场景下 base target 对 form 几乎无效
React/Vue/Angular 等框架中,表单提交通常被 event.preventDefault() 拦截,后续用 fetch 或 axios 提交数据。此时 <form target></form> 和 <base target> 都不触发任何跳转——它们只对原生表单提交(即整页刷新式提交)起作用。
如果你发现加了 <base target="_blank"> 却没效果,先检查控制台是否有 preventDefault 调用;再确认是否用了 router-link 包裹表单、或框架自动重写了 submit 行为。
- 服务端返回 HTML 响应(非 JSON),且未拦截 submit →
<base target>生效 - 前端发 AJAX 请求 →
<base target>完全不参与,跳转逻辑由 JS 控制 - 用
window.open()或location.href导航 → 同样绕过<base>
安全与可访问性风险容易被忽略
<base target="_blank"> 不会自动给表单响应加 rel="noopener noreferrer",而现代浏览器对新窗口 opener 权限管控极严。一旦表单提交后加载的是第三方页面,对方可能通过 window.opener 修改你的原始页面 DOM,甚至窃取用户 session。
更隐蔽的问题是可访问性:屏幕阅读器用户听到“提交表单”后,页面却跳到了新标签页,没有上下文提示,极易迷失。WCAG 明确建议,对非用户主动触发的跨上下文跳转(如表单提交后自动开新页),必须提供明确文本提示或 aria-live 通知。
真正难处理的是混合场景:比如一个页面既有传统表单(依赖 <base>),又有 React 渲染的表单(走 JS 提交)。这时不能只靠 <base> 统一行为,得用脚本补全逻辑,或者干脆放弃 <base target>,全部显式声明。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











