在现代网站开发中,出于用户体验与安全合规(如防止反向 Tabnabbing)双重考虑,通常要求:内部链接(同源)在当前标签页跳转,而外部链接(跨域)强制在新标签页中以 noopener noreferrer nofollow 安全模式打开。直接使用 会无差别作用于所有链接,不可取;而早期基于字符串匹配的 jQuery 方案(如 href.indexOf())易受子域名、协议差异或 URL 编码干扰,鲁棒性差。推荐采用原生 JavaScript 的标准化解析方式——利用 URL 构造函数提取 hostname 进行精确比对。该方法天然支持 http:https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712、https:https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712、https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712 协议相对 URL,以及 #hash、https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712path 等相对路径,并能正确处理端口、子域名等边界情况。以下为完整、可直接部署的解决方案:
<meta charset="UTF-8"><title>外部链接新标签页打开示例<https:><style>
.content { height: 100vh; padding: 2rem; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712style>
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712head>
<body>
<div class="content">
<a href="https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712">首页(同源,当前页)<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712a><br><br>
<a href="#section1">锚点链接(当前页)<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712a><br><br>
<a href="https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712about">相对路径(同源,当前页)<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712a><br><br>
<a href="https:https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712example.com">HTTPS 外链(新页)<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712a><br><br>
<a href="http:https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712github.com">HTTP 外链(新页)<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712a><br><br>
<a href="https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712cdn.jsdelivr.net">协议相对外链(新页)<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712a><br><br>
<a href="mailto:test@example.com">mailto 链接(不处理)<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712a><br><br>
<a href="javascript:void(0)">JavaScript 链接(不处理)<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712a>
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712div>
<div id="section1" class="content">这是锚点目标区域<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712div>
<script>
window.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll('a[href]').forEach(link => {
try {
https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712 跳过非 HTTPhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712HTTPS 协议链接(如 mailto:, tel:, javascript:, # 等)
if (!link.href.startsWith('http')) return;
const url = new URL(link.href);
https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712 仅当 hostname 不匹配当前页面时才设为新窗口
if (url.hostname !== location.hostname) {
link.target = "_blank";
link.rel = "noreferrer nofollow noopener";
link.title = "在新标签页中打开(外部链接)";
}
} catch (e) {
https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712 忽略非法 URL(如 malformed href),避免脚本中断
console.warn("跳过无效链接:", link.href, e);
}
});
});
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712script>
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712body>
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712html><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre><p>✅ <strong>关键优势说明:<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong> <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p><ul><li>✅ <strong>精准同源判断<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong>:new URL(link.href).hostname 提供标准、无歧义的域名提取,自动忽略协议、端口、路径、查询参数和哈希值; <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li><li>✅ <strong>安全默认<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong>:显式设置 rel="noreferrer nofollow noopener",阻断 window.opener 访问,防范钓鱼攻击; <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li><li>✅ <strong>健壮容错<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong>:tryhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712catch 捕获非法 href(如 #、javascript:),确保脚本不崩溃; <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li><li>✅ <strong>零依赖<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong>:纯原生 JS,无需 jQuery 或其他库,兼容所有现代浏览器(IE11+ 需 Polyfill URL); <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li><li>✅ <strong>语义友好<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong>:仅处理 a[href],不影响 <area>、<link> 或其他元素。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712ul><p>⚠️ <strong>注意事项:<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong> <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p><ul><li>若网站部署在子路径(如 https:https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712example.comhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712bloghttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712),location.hostname 仍返回 example.com,因此 href="https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712bloghttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712post" 会被正确识别为同源; <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li><li>如需支持多级子域名通配(如允许 *.example.com 视为同源),可扩展逻辑为 url.hostname.endsWith('.example.com') || url.hostname === 'example.com'; <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li><li>服务端 PHP 方案(如输出前正则替换)虽可行,但无法动态响应前端路由变化(如 SPA 中的 pushState),故客户端 JS 是更通用的选择。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712ul><p>此方案简洁、安全、可维护,是实现“智能外部链接新页打开”的最佳实践。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p></style></https:>
</title>