必须同时设置target="_blank"和rel="noopener noreferrer",仅用前者存在tabnabbing攻击风险;动态生成、服务端模板、Markdown及旧版WebView场景需分别采用DOM操作、模板补全、插件注入或window.open兼容写法确保安全。

如果您在HTML中编写超链接,但点击后未按预期在新窗口或新标签页中打开目标页面,则可能是由于target属性配置不完整或缺失关键安全修饰。以下是解决此问题的步骤:
一、正确使用target="_blank"并搭配rel属性
仅设置target="_blank"会使浏览器在新标签页打开链接,但会赋予新页面对原页面window对象的完全访问权限,存在被恶意页面通过window.opener劫持或性能阻塞的风险。必须同步添加rel属性以切断该危险引用。
1、在标签中同时设置target="_blank"和rel="noopener noreferrer"两个属性。
2、确保rel属性值为noopener noreferrer,顺序不限,但二者缺一不可。
3、验证生成的HTML代码形如:示例链接。
二、使用JavaScript动态创建安全的新窗口链接
当链接由脚本动态生成(如通过document.createElement或innerHTML注入)时,直接写入HTML字符串易遗漏rel属性。采用DOM API可强制控制属性赋值,避免模板渲染疏漏。
1、调用document.createElement('a')创建链接元素。
2、依次设置link.href、link.target和link.rel属性。
3、显式赋值link.rel = 'noopener noreferrer',不可省略。
4、将链接插入文档前,确认其outerHTML包含完整的rel声明。
三、服务端模板中补全rel属性
在PHP、Node.js或Python Jinja等服务端渲染环境中,若模板中硬编码了target="_blank"却未声明rel,输出的HTML将存在安全隐患。需在模板逻辑层统一增强,而非依赖客户端修补。
1、检查所有含target="_blank"的标签模板片段。
2、在对应位置手动追加rel="noopener noreferrer"属性。
3、对CMS或富文本字段输出,配置后端白名单允许rel属性通过过滤器。
4、验证最终HTTP响应体中每个_target="_blank"_链接均携带rel="noopener noreferrer"。
四、针对旧版Safari或WebView的兼容性处理
Safari 10.1以下及部分Android WebView对rel="noreferrer"的支持不完整,无法可靠隔离window.opener。此时需退回到window.open()方式,利用其features参数中的noopener指令实现兼容。
1、移除HTML中target="_blank"链接,改用
2、在click事件处理器中调用window.open(url, '_blank', 'noopener')。
3、注意:此处的noopener是window.open第三个参数features中的字符串,非HTML属性。
4、确保features参数不含空格或非法字符,例如使用'noopener, noreferrer'而非'noopener noreferrer'。
五、Markdown渲染器中注入rel属性
多数Markdown解析器(如marked、remark)默认不为自动识别的外链添加rel属性。若站点内容由Markdown驱动,需通过插件或后处理步骤强制注入,否则静态生成的链接仍不安全。
1、查找所用渲染器是否支持rel属性扩展插件(如remark-external-links)。
2、若无现成插件,在HTML输出阶段遍历所有含target="_blank"的节点。
3、对每个匹配节点执行element.setAttribute('rel', 'noopener noreferrer')。
4、确认最终页面源码中所有外部链接均具备rel="noopener noreferrer"声明。










