在现代网页开发中,出于用户体验与安全规范(如防止 window.opener 漏洞),我们通常需要:
✅ 内部链接(同域名、相对路径、锚点 #、https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712 开头等)—— 在当前标签页打开;
✅ 外部链接(不同 hostname)—— 在新标签页打开,并附加 rel="noreferrer nofollow noopener" 以提升安全性。使用 是错误做法,它会无差别作用于所有链接(包括内部导航),破坏页面体验。而早期 jQuery 方案存在正则匹配不严谨、通配符(如 *.example.com)未解析、this.href.indexOf() 易误判(如 example.com 匹配到 myexample.com)等问题。推荐采用原生 JavaScript 的健壮方案,利用 URL 构造函数精确解析链接主机名:
<meta charset="UTF-8"><title>External Links in New Tab<https:><style>
.content { height: 100vh; padding: 2rem; font-family: -apple-system, 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/29a9f8c8460e5e2be4edde557fd83712stackoverflow.com">Stack Overflow(新标签页)<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712a><br><br>
<a href="http:https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712github.com">GitHub(新标签页)<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712a><br><br>
<a href="https:https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712yourdomain.comhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712blog">同域名子路径(当前页)<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712a>
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712div>
<div id="section1">这里是锚点内容<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 安全解析 href:对相对路径、锚点等也能正确构造 URL
const url = new URL(link.href, location.origin);
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 = link.title
? `${link.title}(外部链接,新窗口打开)`
: "外部链接,新窗口打开";
}
} catch (e) {
https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712 忽略非法 URL(如 href="javascript:void(0)" 或空值),避免报错中断执行
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>使用 new URL(link.href, location.origin) 可正确处理 href="https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712path"、href="#id"、href="." 等相对或特殊链接,避免 href.indexOf(location.hostname) 的误判风险; <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li><li>try...catch 包裹确保脚本健壮性,兼容 href="javascript:..."、href="mailto:..." 等非 HTTP 协议链接; <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li><li>无需依赖 jQuery,体积小、兼容性好(支持 IE11+,若需 IE11 可用 URL polyfill); <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li><li>rel="noreferrer nofollow noopener" 同时满足安全(阻止 window.opener)、SEO(nofollow)及性能(noreferrer 减少 Referer 泄露)三重需求。<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>请勿将此逻辑放在 <head> 中未加 DOMContentLoaded 或 defer 的脚本里,否则可能因 DOM 未就绪导致漏处理; <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li><li>若网站使用前端路由(如 Vue Router、React Router),应改用路由守卫控制跳转行为,而非操作原生 <a> 标签; <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li><li>对于服务端渲染(SSR)场景,PHP 或 Node.js 层也可预处理输出 HTML(例如用 DOMDocument 解析并修改 a 标签),但客户端 JS 方案更通用灵活。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712ul><p>该方案简洁、可靠、可维护,是实现“智能外链新开页”的最佳实践。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p></style></https:>
</title>