target="_blank"必须配rel="noopener",否则新页面可通过window.opener劫持原页面,篡改location、窃取cookie;rel="noopener"仅禁用opener,而rel="noreferrer"还隐藏referer头。

为什么 target="_blank" 必须配 rel="noopener"
不加 rel="noopener" 时,新页面可通过 window.opener 完全控制原页面 —— 这不是理论风险,而是已知的 XSS 攻击链入口。尤其当链接指向不可信域名(比如用户提交的 URL、第三方跳转页)时,原页面的 window.location、document.cookie 都可能被篡改。
rel="noopener" 和 rel="noreferrer" 有什么区别
两者都切断 window.opener,但行为不同:
-
rel="noopener":仅禁用window.opener,Referer头仍会发送 -
rel="noreferrer":既禁用window.opener,也移除Referer头(相当于同时设rel="noopener nofollow")
多数场景用 rel="noopener" 就够了;若需隐藏来源路径(比如敏感页面跳转),才考虑 rel="noreferrer"。
Vue/React 等框架里怎么安全写 target="_blank"
框架不会自动补 rel,必须显式声明。常见错误是只写 target="_blank",或误写成 rel="noopenner"(拼错)。
正确写法示例:
<a href="https://example.com" target="_blank" rel="noopener">外部链接</a>
在 JSX 或模板中注意:
- 不要用字符串拼接生成
rel值,避免空格或大小写错误 - 如果
href动态绑定,确保rel始终存在,不能条件渲染漏掉 - 使用
rel="noopener noreferrer"时,两个值之间必须有空格,不能连写成noopennernoreferrer
浏览器兼容性和 Polyfill 需要吗
rel="noopener" 自 Chrome 49、Firefox 52、Safari 10.1 起原生支持,IE 完全不支持但 IE 已无 window.opener 安全问题(因无 opener 属性)。所以现代项目无需 Polyfill。
唯一要注意的是:如果你用 location.open() 手动开窗,noopener 不生效 —— 这种情况必须用 window.open(url, '_blank', 'noopener') 的第三个参数传特征字符串,且仅对同源窗口可靠。
实际中最容易被忽略的,是 CMS 输出的富文本内容里的 <a></a> 标签 —— 它们往往没带 rel,需要后端清洗或前端 DOM 修补。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











