target="_blank"不加rel="noopener noreferrer"就是安全漏洞,因新页面默认持有window.opener引用,攻击者可执行window.opener.location跳转劫持原页面;noopener切断控制链,noreferrer防referer泄露,二者须小写、无空格、配合target="_blank"才生效。

target="_blank" 不加 rel="noopener noreferrer" 就是安全漏洞
直接写 target="_blank" 会让新页面默认持有 window.opener 引用,攻击者只需一行 JS(比如 window.opener.location = 'https://phishing.com')就能把你的原页面无声劫持。这不是理论风险——TikTok、GitHub 等平台都曾因此被利用。
必须同时加上 rel="noopener noreferrer" 才能切断控制链:
• noopener 是核心:强制新页面的 window.opener 为 null
• noreferrer 是补充:不发送 Referer 头,防敏感路径泄露(如带 token 的 URL)
• 二者必须小写、无空格、无连字符,且只在配合 target="_blank" 时生效
常见错误:
• 只写 rel="noreferrer" —— 旧版 Safari(≤10.0)仍可访问 window.opener
• 写成 rel="NOOPENER" 或 rel="no-opener" —— 浏览器直接忽略
• rel="noopener noreferrer " 末尾带空格 —— 属性值失效
哪些场景必须配 rel,哪些可以不配
rel="noopener noreferrer" 只对真正“新建浏览上下文”的行为起作用,包括:
• <a target="_blank"></a>
• <form target="_blank"></form>
• window.open(url, "_blank")(此时需传 'noopener' 特性字符串,而非 rel 属性)
这些情况不用配:
• target="_self"(默认行为,显式写出来也无需 rel)
• SPA 内部路由跳转(如 /help),target="_blank" 会破坏 history 状态,应避免
• target="_parent" 或 target="_top" —— 它们不创建新上下文,rel 无效
服务端或富文本里怎么自动补 rel
用户生成内容(评论、CMS 编辑器输出)最容易漏掉 rel,靠人工检查不现实。建议在渲染层统一处理:
• 正则匹配所有含 target="_blank" 的 <a></a> 标签
• 若无 rel 属性,注入 rel="noopener noreferrer"
• 若已有 rel="nofollow",合并为 rel="nofollow noopener noreferrer"
• 注意不要覆盖合法值,比如 rel="stylesheet" 出现在 link 标签里就别碰
第三方组件库(如旧版 Ant Design、CKEditor 4.x)常默认不带 rel,上线前务必审计输出 HTML。
iframe 里用 target="_blank" 的实际效果
很多人误以为在 iframe 里点 target="_blank" 会“跳出 iframe”,其实不会:
• 它始终在顶层浏览器新开标签页,和 iframe 无关
• 真想让链接破框跳出,该用 target="_top"(加载到最顶层窗口)
• 如果用了 target="myFrame" 却没匹配到对应 <iframe name="myFrame"></iframe>,行为不一致:Chrome 降级为 _blank,Safari 可能回退到 _self
拼写和大小写必须严格一致:target="MyFrame" 匹配不到 <iframe name="myframe"></iframe>,末尾空格也不行。
最易被忽略的一点:window.open() 和 a 标签的防护逻辑不同——前者靠特性字符串('noopener'),后者靠 rel 属性,混用或遗漏都会留后门。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











