外链必须同时加 rel="noopener noreferrer" 才安全,仅 target="_blank" 存在高危漏洞:新页面可通过 window.opener 修改原页地址或重定向至钓鱼页,且会泄露 Referer;缺一不可,否则 Lighthouse 等工具会标红警告。

外链必须加 rel="noopener noreferrer" 才算安全
只写 target="_blank" 是线上项目高频安全漏洞。新打开的页面能通过 window.opener 直接修改原页面地址、读取 DOM,甚至把用户重定向到钓鱼页。这不是理论风险——攻击者只需在目标页写一行 window.opener.location = "https://fake-login.example" 就能生效。
两个属性缺一不可:
-
noopener:切断window.opener引用,防止恶意控制原页 -
noreferrer:阻止Referer头泄露来源 URL,尤其敏感后台、支付页必须防泄露
漏掉任意一个,Lighthouse 或 Chrome DevTools Security Panel 都会标红警告。旧版 Safari(noopener,但认 noreferrer,所以两个一起写是兜底刚需。
target="_blank" 写错就等于没开新页
常见错误不是“要不要加”,而是“怎么加”:
立即学习“前端免费学习笔记(深入)”;
-
target="blank"(漏下划线)→ 浏览器当普通窗口名处理,因找不到对应窗口,fallback 到_self,当前页跳转 -
target="_new"或target="new"→ 非标准值,所有现代浏览器都忽略,同样退化为_self -
target="_blank"单独存在 → 安全后门敞开,等同于没防护
W3C 明确只承认五种合法值:_self、_blank、_parent、_top、framename。其他全是无效字符串,别信“看着像”的写法。
href 值写错会让安全属性失效
再安全的 rel 也救不回一个崩掉的链接。外链 href 必须带完整协议:
- ✅
href="https://example.com"—— 正确,协议 + 域名 - ❌
href="www.example.com"—— 错误,被解析成相对路径,实际请求http://your-site.com/www.example.com - ❌
href="//example.com"—— 协议相对地址,HTTPS 页面里可能降级为 HTTP,且不触发rel="noreferrer"的 Referer 保护逻辑 - ❌
href="#"或href="javascript:void(0)"—— 不是外链,加rel没意义,还可能干扰 SEO 和可访问性
href 错了,浏览器根本不会把它当外链处理,rel="noopener noreferrer" 就只是个摆设。
框架里动态生成 a 标签容易绕过安全校验
Vue/React 中用 @click.prevent="window.open(url)" 替代原生 <a>,看似灵活,实则埋雷:
- 右键菜单丢失“复制链接地址”功能
- SEO 无法识别,搜索引擎不抓取该链接
- SSR 环境下直接报
ReferenceError: window is not defined - 如果
url变量为空或未定义,生成的href="undefined"导致点击无响应
正确做法是在模板中老老实实用原生 <a>,并通过 computed 或 useEffect 校验 href 是否合法,再决定是否渲染。安全属性不是锦上添花,是每个外链的硬性准入条件。



















