rel="noopener"能防窗口劫持,因为它使新页面的window.opener为null,彻底阻断其通过window.opener.location等操作劫持原页面的能力;该属性必须与target="_blank"配合使用才生效。

为什么 rel="noopener" 能防窗口劫持
当用 target="_blank" 打开新页面时,新页面可通过 window.opener 访问原页面的 window 对象——这意味着它能调用 window.location.replace()、读取历史记录,甚至执行脚本篡改原页。攻击者常利用这点做钓鱼或跳转劫持。rel="noopener" 会切断这个引用,让新页面的 window.opener 为 null,彻底阻断控制链。
rel="noopener" 必须和 target="_blank" 一起用才生效
单独写 rel="noopener" 没有意义,浏览器只在存在 target="_blank"(或 target="_popup" 等非当前上下文目标)时才启用 opener 隔离逻辑。
正确写法示例:
<a href="https://example.com" target="_blank" rel="noopener">外部链接</a>
常见错误:
- 漏掉
target="_blank",只加rel="noopener" - 写成
rel="noopen"或rel="no-opener"(拼写错误) - 在
<form target="_blank"></form>中忘记加rel(rel属性不适用于form,需改用 JavaScript +window.open()并显式传null)
要不要加 rel="noreferrer"?
rel="noreferrer" 会同时禁用 window.opener 和 Referer 头,比 noopener 更严格。但要注意:
- 如果后端依赖 Referer 做简单来源校验(如防止图片盗链),加了
noreferrer可能导致请求被拒 -
noreferrer在部分旧版 Safari(≤11.1)中会隐式降级为noopener,行为不一致 - 现代最佳实践是:对外部不可信链接用
rel="noopener noreferrer";对需要传递 Referer 的合作方链接,只用rel="noopener"
Vue/React 等框架里容易漏掉的地方
模板中写死的 <a></a> 标签容易补上 rel,但动态生成的链接常被忽略:
- Vue 中通过
v-html渲染富文本时,原始 HTML 若没带rel,不会自动注入 - React 中用
dangerouslySetInnerHTML同理,需提前清洗或用linkify-it等库统一处理 - 服务端渲染(SSR)场景下,若链接由后端拼接且未预留
rel字段,前端无法事后修补
最稳妥的方式是在链接生成环节就强制注入,而不是依赖运行时补全。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











