如何在URL()构造函数中保留URL主机/域名的大小写
URL主机名大小写保留问题
JavaScript的URL()构造函数会自动将主机名/域名规范化为小写:
(new URL('https://WWW.EXAMPLE.COM/THIS/is/a/PATH')).href // => 'https://www.example.com/THIS/is/a/PATH'
核心疑问
- 获取保留主机名大小写的
hostname和href字符串的最简方法是什么? - 是否存在比「手动解析域名后替换
URL.href结果」更优的方案?
需求说明:希望对URL进行查询/操作(例如移除不必要的查询参数),但同时保留域名的大小写。虽然域名本身不区分大小写,但有时主机名会加入大写字符提升可读性(比如expertsexchange.com这类案例)。
可行方案
方案1:手动替换规范化后的域名(最直接)
先用URL对象完成所有需要的URL操作,最后把小写域名替换回原始大小写版本即可,这是目前最简便的实现方式。
示例代码:
const originalUrl = 'https://WWW.EXAMPLE.COM/THIS/is/a/PATH?foo=bar&baz=qux'; const urlObj = new URL(originalUrl); // 提取原始主机名(正则匹配协议后的域名部分) const originalHostname = originalUrl.match(/https?:\/\/([^\/]+)/)[1]; // 执行URL操作:比如删除指定查询参数 urlObj.searchParams.delete('baz'); // 替换域名,得到保留大小写的最终URL const finalHref = urlObj.href.replace(urlObj.hostname, originalHostname); console.log(finalHref); // => 'https://WWW.EXAMPLE.COM/THIS/is/a/PATH?foo=bar'
方案2:封装工具函数(适合频繁使用场景)
如果需要多次处理这类URL,可以封装工具函数整合逻辑,避免重复代码:
function createCasePreservedUrl(originalUrl) { const urlObj = new URL(originalUrl); const originalHostname = originalUrl.match(/https?:\/\/([^\/]+)/)[1]; // 自定义方法:获取保留大小写的完整URL urlObj.getCasePreservedHref = function() { return this.href.replace(this.hostname, originalHostname); }; // 自定义方法:获取原始大小写的主机名 urlObj.getOriginalHostname = function() { return originalHostname; }; return urlObj; } // 使用示例 const myUrl = createCasePreservedUrl('https://WWW.EXAMPLE.COM/THIS/is/a/PATH?foo=bar'); myUrl.searchParams.delete('foo'); console.log(myUrl.getCasePreservedHref()); // => 'https://WWW.EXAMPLE.COM/THIS/is/a/PATH' console.log(myUrl.getOriginalHostname()); // => 'WWW.EXAMPLE.COM'
关于原生方案的说明
浏览器原生URL对象遵循RFC 3986规范,该规范明确主机名大小写不敏感,因此原生实现会自动将其转为小写,没有提供保留原始大小写的API。目前没有比「替换域名」更优的原生方案,上述手动替换方式已是最简且可靠的实现。
内容的提问来源于stack exchange,提问作者Leftium
相关产品推荐
相关产品推荐

