rel="noopener noreferrer"必须与target="_blank"配合使用才生效,单独添加无安全作用;它仅在创建新浏览上下文(如、、window.open(url, "_blank"))时切断opener引用并阻止referer泄露。

rel="noopener noreferrer"必须和target="_blank"一起用才生效
单独写rel="noopener noreferrer"在<a></a>标签里,但没配target="_blank",浏览器根本不会触发opener隔离逻辑。它只在创建新浏览上下文(新开tab/window)时起作用,包括:<a target="_blank"></a>、<form target="_blank"></form>、window.open(url, "_blank")这三类场景。
常见错误现象:
- 富文本编辑器自动给外链加
target="_blank",但服务端没补rel,上线后被安全扫描标为高危 - 写成
<a href="..." rel="noopener noreferrer"></a>却漏掉target="_blank",属性存在但完全无效 - 在
target="_self"或target="_parent"上硬塞rel="noopener",既不防劫持也不影响 Referer
window.open()不能靠rel属性控制opener
rel是HTML属性,对JS主动打开的窗口不起作用。写window.open(url, "_blank", "noopener")是错的——noopener不是合法的features字符串参数。
正确做法分情况:
- 同源场景:用
window.open(url, "_blank", "noopener=yes")(Chrome/Edge支持),再配合HTML里rel="noopener noreferrer"双重保险 - 跨域或兼容性要求高:改用
location.replace()跳转 + 新窗口监听,或直接放弃JS开窗,回归<a target="_blank" rel="noopener noreferrer"></a> - 绝对不要只写
window.open(url)或window.open(url, "_blank"),默认保留window.opener引用
noopener和noreferrer各管什么,顺序不能乱
noopener是安全底线,强制新页面window.opener === null;noreferrer是隐私补充,让HTTP请求头不带Referer字段,同时在多数现代浏览器中隐式启用noopener——但它不可替代前者。
关键细节:
- 旧版Safari(≤12.0)和某些WebView中,
rel="noreferrer"不保证window.opener为null,必须显式写noopener - 写成
rel="noreferrer noopener"看似一样,但部分Markdown渲染器或CMS解析器会按顺序取第一个合法值,可能只认noreferrer而忽略noopener - 如果业务强依赖
Referer(比如来源统计),至少保留rel="noopener",别为Referer放弃安全
服务端或富文本输出时容易漏掉rel属性
用户粘贴链接、CMS后台生成HTML、评论区自动识别URL……这些场景下,target="_blank"常被自动加上,但rel几乎从不自动补全。这才是真实风险高发区。
建议处理方式:
- 服务端渲染阶段统一匹配
<a>]*target=["']_blank["'][^>]*></a>,注入rel="noopener noreferrer"(若原无rel)或合并进已有rel值(如rel="nofollow"→rel="nofollow noopener noreferrer") - 前端富文本编辑器(如Tiptap、Quill)配置输出规则,确保外链自动带上完整
rel - 上线前用Lighthouse或axe跑一遍,检查
target="_blank"是否都配了rel="noopener",别等被红队打穿才补
真正难的是让所有生成环节都记得这件事——不是写一次就完事,而是每次输出都要过这一关。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











