rel="noopener"用于切断window.opener引用,防止新页面通过target="_blank"劫持原页面,必须与target="_blank"共用才生效,单独使用无效,且需小写无连字符。

rel="noopener" 是为了切断 window.opener 引用
不加 rel="noopener",只要用了 target="_blank",新页面就能通过 window.opener 直接控制原页面——哪怕跨域也成立。这不是漏洞,是浏览器默认行为。恶意页面可以立刻执行 window.opener.location.href = "https://fake-login.example",把你的用户无声劫持到钓鱼页。
加了 rel="noopener" 后,新页面中 window.opener 永远是 null,所有基于它的操作(读取 history、调用 location.replace、写 document)都会失败或静默忽略。
必须和 target="_blank" 一起用才生效
rel="noopener" 单独写在 <a> 标签里但没配 target="_blank",浏览器直接忽略。它只在创建新浏览上下文时起作用:
<a href="..." target="_blank" rel="noopener">-
<form target="_blank">(同样要加rel="noopener") -
window.open(url, "_blank")不受该属性影响——JS 打开的窗口需用features参数控制,如"noopener=yes"(仅 Chrome/Edge 支持)
常见错误写法和漏点
真实项目中最容易栽在动态生成环节,而不是手写 HTML:
立即学习“前端免费学习笔记(深入)”;
- Markdown 渲染器自动加
target="_blank",但不补rel属性 - 富文本编辑器导出的 HTML 保留了
target="_blank",却没做rel合并处理 - 服务端模板拼接链接时硬编码
target="_blank",但忘了判断是否已有其他rel值(比如rel="nofollow"),直接覆盖成rel="noopener"导致语义丢失 - 写成
rel="NOOPENER"或rel="no-opener"—— 必须小写、无连字符,否则无效
noopener 和 noreferrer 不是一回事
rel="noopener" 只管安全:断 opener;rel="noreferrer" 只管隐私:不发 Referer 头。二者职责不同,不能互相替代:
- 旧版 Safari(≤12.0)中,
rel="noreferrer"不保证window.opener === null,必须显式写noopener - 如果业务依赖 Referer(如来源归因),别为省事只加
noreferrer而放弃noopener - 推荐组合写法:
rel="noopener noreferrer",但要注意顺序:某些 CMS 或 Markdown 解析器只认第一个合法值,所以noopener应放在前面



















