根本原因是缺少rel="noopener noreferrer",现代浏览器因安全策略主动降级行为;合法target值仅_self、_blank、_parent、_top及自定义framename五种。

target="_blank" 被拦截的根本原因不是代码写错
浏览器拦截 target="_blank" 链接,几乎从不因为属性拼写错误(比如写成 target="blank"),而是因为缺少 rel="noopener noreferrer"。现代浏览器(Chrome 92+、Firefox 88+、Safari 15.4+)在检测到新页持有 window.opener 引用时,会主动降级行为——可能静默跳转到当前页,或弹出警告,或控制台报 Blocked a frame with origin https://www.php.cn/link/263b1243ca2dbeb358777ceabc4a2e4c from accessing a cross-origin frame。
rel 属性漏写或写错的常见翻车点
这些看似细微的差异,都会导致拦截或安全漏洞:
-
rel="noopener"单独存在:不够,noreferrer缺失会导致 Referer 泄露,部分旧版 Safari 仍可能暴露window.opener -
rel="noreferrer"单独存在:noopener没加,劫持风险仍在,Chrome/Firefox 会保留 opener 引用 -
rel="noopener noreferrer"顺序颠倒(如noreferrer noopener):合法,不影响功能 -
rel="noopener no referrer":含空格或错词,浏览器当无效值处理,等同于没写 - 服务端模板(如 Jinja/PHP)输出时被过滤器删掉
rel:CMS 或富文本编辑器常默认禁用该属性,需手动加白名单
动态生成链接时怎么确保 rel 不丢
用字符串拼接 HTML(比如 innerHTML += '@#@#@#@#@#@#@#@#@#@0')极易漏掉 rel。更稳的方式是走 DOM API:
- 用
document.createElement('a')创建元素 - 依次赋值:
link.href = url、link.target = '_blank'、link.rel = 'noopener noreferrer' - 插入前检查
link.outerHTML,确认三项都在 - 避免在异步回调(如
fetch().then())里调用form.submit(),否则可能触发无用户交互的弹窗拦截
iframe 隐藏窗口方案绕过拦截
当必须用表单提交且目标是新上下文,又担心 target="_blank" 被拦(尤其 Safari 或自动 submit 场景),可用隐藏 iframe 模拟:
- 页面中放一个
<iframe name="hidden-frame" style="display:none"></iframe> -
<form target="hidden-frame"></form>,name 必须完全匹配(大小写敏感、无空格) - 监听
iframe.onload或用MutationObserver捕获响应内容 - 注意:该 iframe 必须与表单同源,否则加载失败且无提示
真正难的不是写对 target,而是在 CMS、Markdown 渲染、服务端模板、WebView 容器这些环节里,让 rel="noopener noreferrer" 始终不被过滤、不被覆盖、不被忽略——它得像 href 一样成为基础设施级的默认项。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











