
该问题源于浏览器对不以标准协议(如 https://)开头的 href 值自动补全为相对路径,导致当前页面 URL 被错误前置;根本原因是原始链接中的协议分隔符被异常编码(如 https; 代替 https:),使 .replace() 后的结果无法通过浏览器的 URL 解析校验。
该问题源于浏览器对不以标准协议(如 `https://`)开头的 `href` 值自动补全为相对路径,导致当前页面 url 被错误前置;根本原因是原始链接中的协议分隔符被异常编码(如 `https;` 代替 `https:`),使 `.replace()` 后的结果无法通过浏览器的 url 解析校验。
在开发 Steam 社区相关用户脚本时,你可能会遇到这样一种典型现象:使用 .replace() 清理 href 中的跳转代理前缀(如 https;//steamcommunity.com/linkfilter/?u=)后,链接并未变成预期的纯净目标地址,反而被浏览器“悄悄”拼接上了当前页面 URL —— 这并非脚本逻辑错误,而是浏览器 URL 解析机制触发的隐式相对路径转换。
? 问题本质:协议格式失效引发解析降级
浏览器在设置 <a></a> 元素的 href 属性时,会严格校验其是否为绝对 URL。若值不以 http://、https://、// 等合法协议或协议相对形式开头,浏览器将默认将其视为相对路径,并自动以当前页面 URL 为基准进行补全(类似 ./target 的行为)。
而你的原始字符串中使用的是 https;(分号)而非 https:(冒号),这导致:
- 正则成功替换了
https;\/\/steamcommunity...部分; - 但剩余字符串以
https;开头 → 不被识别为有效协议 → 浏览器判定为相对路径 → 补全当前域。
✅ 正确的协议格式必须是 https:(英文冒号),而非 https;(分号)。该分号很可能是网页 HTML 源码中为规避爬虫或反垃圾策略所做的人为编码混淆,需同步解码。
✅ 推荐解决方案:先解码,再替换,最后强制标准化
jQuery(document).on("mouseenter", "a", function(event) {
let href = jQuery(this).prop("href");
// 1. 对 href 进行 HTML 解码(处理 & {
const txt = document.createElement("textarea");
txt.innerHTML = str;
return txt.value;
};
href = decodeHtml(href);
// 2. 使用更鲁棒的正则:兼容 https: 和 https; 变体,并确保匹配完整协议部分
const cleaned = href.replace(
/https?:\/\/steamcommunity\.com\/linkfilter\/\?u=/i,
""
);
// 3. 【关键】确保结果以标准协议开头,否则显式补全为绝对 URL
if (/^https?:\/\//i.test(cleaned)) {
jQuery(this).prop("href", cleaned);
} else {
// 若仍不合规(如残留 https; 或无协议),尝试修复冒号并重试
const repaired = cleaned.replace(/^https;\/\//i, "https://");
jQuery(this).prop("href", repaired);
}
});
⚠️ 注意事项与最佳实践
-
永远避免直接操作未解码的
href属性值:DOM 中读取的href是浏览器解析后的绝对 URL,但某些网站会故意在 HTML 源码中写入混淆字符串(如https;),此时应优先从element.getAttribute('href')获取原始字符串,再解码。 -
推荐更安全的获取方式(防 DOM 自动修正):
const rawHref = this.getAttribute("href"); // 获取原始 HTML 属性值 const decoded = decodeHtml(rawHref); -
不要依赖
mouseenter时机:该事件可能多次触发且非首次加载。建议改用document.addEventListener("DOMContentLoaded", ...)+MutationObserver监听动态插入的链接,或使用jQuery(document).on("click", "a", ...)在点击前即时修复(更可靠)。 -
协议校验可增强健壮性:
function isValidAbsoluteUrl(str) { try { new URL(str); return str.startsWith("http://") || str.startsWith("https://"); } catch { return false; } }
? 总结
这不是 .replace() 失效,而是浏览器 URL 解析规则与前端数据呈现差异共同导致的“幻觉 bug”。解决核心在于:还原原始语义 → 精准替换 → 强制协议合规。只要确保最终赋值给 href 的字符串能通过 new URL(...) 构造且以 https:// 开头,浏览器就绝不会再擅自拼接当前地址。在 Steam 生态等常做链接混淆的场景中,HTML 解码 + 协议标准化应成为用户脚本的标配步骤。










