从URL中获取协议、域名和端口

405

我需要从给定的URL中提取完整的协议、域名和端口号。例如:

https://localhost:8181/ContactUs-1.0/contact?lang=it&report_type=consumer
>>>
https://localhost:8181
19个回答

718
const full = location.protocol + '//' + location.host;

3
@Randomblue 这是什么意思?您将获得 about://。不过,我很好奇 about:blank 的使用场景是什么?我不确定是否有任何浏览器会在 about:blank 中注入插件资源,但似乎这可能是唯一的使用情况。 - Shef
3
如果你有一个URL字符串,这个方法完全不起作用,是吗?也就是说,你需要在location上才能使它起作用。 - Nick T
1
抱歉回复晚了,@NickT。是的,它不会这样做。请使用David提供的好的解决方案 - Shef
1
这个答案应该被选择为正确答案。它很干净,使用了标准的位置对象。 - Mohit Gangrade
26
дҪ еҸҜд»ҘдҪҝз”Ёlocation.hostд»Јжӣҝlocation.hostname + location.portеҗ—пјҹиҜ·жіЁж„ҸпјҢдёӨиҖ…зҡ„еҗ«д№үзӣёеҗҢгҖӮ - c24w
显示剩余5条评论

225

没有一个答案完全回答了问题,该问题要求任意 url,而不是特定于当前页面的 url。

方法1:使用 URL API(注意:不支持 IE11)

您可以使用 URL API(不支持 IE11,但在其他地方可用)。

这还使得访问搜索参数变得容易。另一个好处是它可以在 Web Worker 中使用,因为它不依赖于 DOM。

const url = new URL('http://example.com:12345/blog/foo/bar?startIndex=1&pageSize=10');

方法二(旧方法):使用浏览器内置的DOM解析器

如果您需要在较旧的浏览器上运行,请使用此方法。

//  Create an anchor element (note: no need to append this element to the document)
const url = document.createElement('a');
//  Set href to any path
url.setAttribute('href', 'http://example.com:12345/blog/foo/bar?startIndex=1&pageSize=10');

就是这样!

浏览器内置的解析器已经完成了它的工作。现在你可以只获取你需要的部分(注意,这适用于上述两种方法):

//  Get any piece of the url you're interested in
url.hostname;  //  'example.com'
url.port;      //  12345
url.search;    //  '?startIndex=1&pageSize=10'
url.pathname;  //  '/blog/foo/bar'
url.protocol;  //  'http:'

额外奖励:搜索参数

很可能您也想要分解搜索URL参数,因为'?startIndex=1&pageSize=10'本身并不太可用。

如果您以上使用了方法一(URL API),您只需使用searchParams getters:

url.searchParams.get('startIndex');  // '1'

或者获取所有参数:

function searchParamsToObj(searchParams) {
  const paramsMap = Array
    .from(url.searchParams)
    .reduce((params, [key, val]) => params.set(key, val), new Map());
  return Object.fromEntries(paramsMap);
}
searchParamsToObj(url.searchParams);
// -> { startIndex: '1', pageSize: '10' }

如果你使用的是Method 2(旧方法),你可以使用类似这样的代码:

// Simple object output (note: does NOT preserve duplicate keys).
var params = url.search.substr(1); // remove '?' prefix
params
    .split('&')
    .reduce((accum, keyval) => {
        const [key, val] = keyval.split('=');
        accum[key] = val;
        return accum;
    }, {});
// -> { startIndex: '1', pageSize: '10' }

你是在一个 http 页面上进行吗?如果没有指定,它将从当前位置“继承”。 - Stijn de Witt
6
这是一个很棒的回答,应该得到更多的投票,因为这个回答不仅适用于当前位置,而且适用于任何网址,而且这个回答利用了浏览器内置的解析器,而不是自己构建一个(我们无法像这个回答一样做得那么好或那么快!)。 - Stijn de Witt
这在绝对URL的情况下运行良好。但是在相对URL和跨浏览器的情况下会失败。有什么建议吗? - Gururaj
搜索=search.split('?')[1]; 真的吗?!?!那么search = search.substr(1);怎么样?更安全和更快,因为它只创建了一个字符串而不是两个... - Alexis Wilke
这是正确的答案...需要标记为答案 @wezzy - shivi
显示剩余6条评论

209

3
为了补充完整:位置是HTML5定义的,它实现了在WHATWG上定义的URLUtils接口,并包括origin属性。 - Ciro Santilli OurBigBook.com
6
来自2015年的问候...不幸的是,根据MDN上的兼容性表格,URLUtils在所有浏览器中仍未得到正确实现。但是似乎与2013年相比,origin属性的支持稍微有所改善,但由于Safari没有正确实现,它仍然不适用于生产环境。抱歉各位 :( - totallyNotLizards
1
它在IE中也不起作用,返回“未定义”。 - Siddhartha Chowdhury
IE11的bug已经被修复了:https://connect.microsoft.com/IE/feedback/details/1763802/location-origin-is-undefined-in-ie-11-on-windows-10-but-works-on-windows-7 - Ricardo Vigatti
4
你好,来自2020年的问候:现在该功能在所有浏览器上都可用,唯独Opera浏览器未知。这个信息来源于这里:https://developer.mozilla.org/en-US/docs/Web/API/Window/location#Browser_compatibility。 - OuuGiii
显示剩余2条评论

192

先获取当前地址。

var url = window.location.href

然后只需解析该字符串

var arr = url.split("/");

你的网址是:

var result = arr[0] + "//" + arr[2]

9
这适用于URL字符串,其中location对象不可用(即在浏览器外的JavaScript中)。 - Thamme Gowda
1
David Calhoun的答案使用内置解析器(如location),但可用于任何网址。看看它很不错。 - Stijn de Witt
12
将其转化为一行代码:window.location.href.split('/').slice(0, 3).join('/'),意思是获取当前网页的 URL,并只取前三个斜杠之间的部分,最后将它们用斜杠连接起来。 - Ryan McGeary
你如何在Node上实现这个功能? - Playdome.io
14
窗口位置.来源 - int soumen
看起来自2013年5月以来支持location.protocol(https://caniuse.com/#feat=mdn-api_location_protocol)。当回答这个问题时,使用`location.protocol`是有意义的,现在你可以使用它。 - A1rPun

54
如前所提到,还有一个目前不完全支持的window.location.origin,但我不喜欢使用它或创建一个新变量来使用,而是更喜欢检查它,并在未设置时设置它。
例如:
if (!window.location.origin) {
  window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');
}

我实际上在几个月前写过这个问题的解决方法,A fix for window.location.origin


1
这是我第一次知道 window.location.origin 的存在。谢谢。^^ - EThaiZone

36

主机

var url = window.location.host;

返回 localhost:2679

主机名

var url = window.location.hostname;

返回 localhost


谢谢!我找不出为什么localhost显示为 localhost/ 而不是 localhost:3000 - Tyler Youngblood

27

为什么不使用:

let full = window.location.origin

4
在回答已有答案的旧问题时,解释你的答案带来了什么新信息是很有用的,并且要承认时间的流逝是否会影响答案。 - Jason Aller
这是最好的一个,一定是正确答案 2022。 - Germán Acosta
这只是重复了同样的解决方案(window.location.origin),包括2013年的这个答案https://dev59.com/d2w05IYBdhLWcg3w6GLH#16843537(唯一的区别是它将该值分配给了一个变量,这与所提问的问题无关)。它应该被删除,但由于得分较高需要管理员来进行操作。 - TylerH

26

window.location.origin就足以得到相同的结果。


1
那很容易解决了我的问题。谢谢 @intsoumen - Turker Tunali
感谢您的赞赏 @TurkerTunali - int soumen
这只是重复了相同的解决方案(window.location.origin),包括2013年的这个答案https://dev59.com/d2w05IYBdhLWcg3w6GLH#16843537 - 它应该被删除,但由于高分需要管理员。 - TylerH

16

protocol 属性设置或返回当前 URL 的协议,包括冒号(:)。

这意味着如果你只想获取 HTTP/HTTPS 部分,可以像这样做:

var protocol = window.location.protocol.replace(/:/g,'')

您可以使用以下域名:

var domain = window.location.hostname;

对于端口,您可以使用:

var port = window.location.port;

请注意,如果端口在URL中不可见,则端口将是一个空字符串。例如:

如果您需要在没有端口的情况下显示80/443,请使用

var port = window.location.port || (protocol === 'https' ? '443' : '80');

9

的确,window.location.origin在遵循标准的浏览器中可以正常使用,但你知道吗?IE并没有遵循标准。

因此,在IE、FireFox和Chrome中,以下方法对我有效:

var full = location.protocol+'//'+location.hostname+(location.port ? ':'+location.port: '');

但是为了可能的未来增强功能可能会引起冲突,我在“location”对象之前指定了“window”引用。

var full = window.location.protocol+'//'+window.location.hostname+(window.location.port ? ':'+window.location.port: '');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接