target="_blank"必须配rel="noopener noreferrer"才安全,否则新页面可通过window.opener篡改原页或泄露Referer;合法target值仅_self、_blank、_parent、_top和framename五种,其他如_new均为非标准写法。

target="_blank" 单独使用等于留后门,必须配 rel="noopener noreferrer" 才算落地;其他像 "_new"、"_window" 这类写法浏览器根本不认,最终退化为当前页跳转。
为什么 target="_blank" 必须加 rel="noopener noreferrer"
不加 rel="noopener" 时,新页面能通过 window.opener 直接调用 location.replace() 或读取原页 DOM,常见现象包括:原页面被悄悄跳转到钓鱼页、返回后发现地址已变、控制台报跨域访问被拦截(其实是防御性报错)。rel="noreferrer" 不是可选项——它阻止 Referer 头泄露来源 URL,避免隐私外泄。漏掉任意一个,安全就不成立。
现代浏览器(Chrome 49+、Firefox 52+、Safari 10.1+)支持 noopener,但旧版 Safari 需靠 noreferrer 兜底,所以两个一起写最稳妥。
合法的 target 值只有这五种
W3C 和 HTML Living Standard 明确只承认以下值,其余全是“浏览器尽力而为”的非标准行为:
立即学习“前端免费学习笔记(深入)”;
-
_self:默认行为,在当前标签页打开;显式写出来通常只为覆盖<base target="_blank"> -
_blank:唯一推荐用于新开页的值;注意是下划线开头,target="blank"(漏下划线)会被当作文本窗口名,最终 fallback 到_self -
_parent:仅在嵌套<iframe>时有效,指向父级上下文;若无父级,则等同_self -
_top:跳出所有 iframe 层级,在顶层窗口加载;常用于防被第三方 iframe 套住后无法跳转 -
framename:匹配页面中某个<iframe name="xxx">;名称大小写敏感,不能含空格或特殊字符
像 _new、_search、_window 这类“看着像”的值,浏览器不会报错,但也不会按预期执行——它们只是被当作自定义窗口名,因找不到对应窗口,最终仍 fallback 到 _self。
iframe 场景下 target 容易失效或跳转错位
在含 <iframe> 的页面里,target 行为高度依赖 sandbox 属性和 allow 权限:
- 如果
<iframe sandbox>没加allow-scripts或allow-popups,target="_blank"会被静默忽略 -
<iframe name="myframe">+target="myframe"会导致链接在该 iframe 内跳转,不是新开页 - 跨域 iframe 中,部分浏览器可能因安全策略把
target="_blank"降级为_self
另外,target="_parent" 和 target="_top" 在现代 SPA 中极少使用,误写成 target="parent"(缺下划线)会触发非标准窗口复用逻辑,且没 noopener 保护,风险更高。
Vue/React 里动态生成 a 标签的坑
框架不改变 HTML 语义,但容易绕过原生安全机制:
- 用
@click.prevent="window.open(url)"替代<a>→ 右键菜单丢失“复制链接地址”,SSR 环境直接报ReferenceError: window is not defined - 动态拼接
href时未校验,导致href="undefined"或href="javascript:void(0)"→ 点击无响应或意外执行 JS - 在
<router-link>或<Link>中硬塞target→ 这些组件不支持该属性,会被忽略,必须退回原生<a>
真正麻烦的是:很多人以为加了 target="_blank" 就完事了,却忘了框架模板里也要手动补上 rel="noopener noreferrer"——React/Vue 都不会自动帮你加。
最常被忽略的一点:target 是 HTML attribute,不是 JS property;你在代码里改 anchor.target = "_blank",它不会自动带上 rel,安全缺口依然存在。写死在模板里,才是唯一可靠方式。



















