必须搭配rel="noopener noreferrer"才安全,否则新页可通过window.opener劫持原页、窃取信息或阻塞主线程;单独用target="_blank"存在严重安全与性能风险。

target="_blank" 单独写,浏览器确实会新开标签页,但新页面能通过 window.opener 控制你的原页面——这不是“可能”,而是默认行为;必须搭配 rel="noopener noreferrer" 才算安全可用。
为什么只加 target="_blank" 会出问题
旧写法会让目标页拿到你页面的完整 window 对象引用。它能执行 window.opener.location = 'https://evil.com' 直接劫持你原来的标签页,也能读取你的 DOM、Cookie(同源时),甚至拖慢主线程——因为两个页面共享渲染进程。
常见现象包括:
- 点开外部链接后,切回原标签页发现地址已跳转
- 原页面明显卡顿,尤其在新页运行 heavy JS 时
- 控制台出现
Blocked a frame with origin ... from accessing a cross-origin frame报错(其实是浏览器在拦截攻击)
rel="noopener noreferrer" 怎么写才对
顺序不重要,但两个值必须同时存在,缺一不可。漏掉 noopener 就等于没关后门;只写 noreferrer 则完全不防 opener 劫持——Safari 旧版甚至会忽略 noreferrer 的安全效果。
正确示例:@#@#@#@#@#@#@#@#@#@0
常见错误:
-
rel="noopener"或rel="noreferrer"单独出现 - 拼错成
ref="noopener"(少一个l) - 在内部链接(如
/about、#section2)上滥用该组合 - CMS 富文本编辑器自动过滤
rel属性,实际输出缺失
动态生成链接时怎么补 rel
JS 创建或模板渲染容易漏掉 rel,尤其是用 innerHTML 拼字符串时。必须用 DOM API 显式赋值:
const link = document.createElement('a');link.href = 'https://example.com';link.target = '_blank';link.rel = 'noopener noreferrer'; // 这行不能省
注意:
- 确保在
DOMContentLoaded后操作 DOM - 区分内外链:用
document.querySelectorAll('a[href^="http"]:not([href*="yoursite.com"])')避免误伤 - 检查是否已有
rel,避免重复添加(如某些框架会自动加) - 别用
onclick="window.open()"替代原生a标签——会丢失右键菜单、SEO 和可访问性支持
<base target="_blank"> 为什么不该用
虽然它能让所有链接默认新窗口打开,但它无法为每个链接单独配 rel,导致全部链接都暴露在 window.opener 风险下。
更严重的是:
- 它会影响表单提交、图片
src、CSS@import等所有带 URL 的行为 - 锚点链接(如
#top)也会被强制新窗口打开,破坏页面内导航 - 在 React/Vue 中与路由逻辑冲突,
<router-link></router-link>不支持target,强行加 base 会导致意外跳转
真正需要统一控制时,应该封装一个安全的 <safelink></safelink> 组件,而不是依赖 <base>。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











