如何从 JavaScript 中的字符串中提取基本 URL?

Posted

技术标签:

【中文标题】如何从 JavaScript 中的字符串中提取基本 URL?【英文标题】:How to extract base URL from a string in JavaScript? 【发布时间】:2010-11-28 02:21:41 【问题描述】:

我正在尝试找到一种相对简单可靠的方法来使用 javascript(或 jQuery)从字符串变量中提取基本 URL。

例如,给定如下内容:

http://www.sitename.com/article/2009/09/14/this-is-an-article/

我想得到:

http://www.sitename.com/

正则表达式是最好的选择吗?如果是这样,我可以使用什么语句将从给定字符串中提取的基本 URL 分配给新变量?

我对此进行了一些搜索,但我在 JavaScript 世界中找到的所有内容似乎都围绕着使用 location.host 或类似文件从实际文档 URL 收集这些信息。

【问题讨论】:

现在的答案应该是this one below 【参考方案1】:

编辑:有人抱怨它没有考虑协议。所以我决定升级代码,因为它被标记为答案。对于那些喜欢单行代码的人......对不起,这就是我们使用代码最小化器的原因,代码应该是人类可读的,这种方式更好......在我看来。

var pathArray = "https://somedomain.com".split( '/' );
var protocol = pathArray[0];
var host = pathArray[2];
var url = protocol + '//' + host;

或者从下面使用Davids solution。

【讨论】:

感谢您的回复,但我再次尝试从字符串中提取基本 URL,而不是实际的文档 URL。我认为这对我没有帮助 - 但如果我错了,请纠正我。 pathArray = String("YourHost.com/url/nic/or/not").split( '/' ); host = pathArray[2]; 知道了 - 感谢 Rafal 和 daddywoodland!我最终使用: url = 'sitename.com/article/2009/09/14/this-is-an-article'; pathArray = (url).split('/');主机 = 'http://' + pathArray[2];我认为 Rafal 的示例只是省略了我正在处理的所有字符串中存在的“http://”,在这种情况下 pathArray[2] 就是您需要的。如果没有“http://”前缀,pathArray[0] 就是那个。再次感谢。 为什么都是变量声明? url = 'sitename.com/article/2009/09/14/this-is-an-article'; newurl = 'http://' + url.split('/')[0]; pathArray = window.location.href.split('/');协议 = pathArray[0];主机=路径数组[2]; url = 协议 + '://' + 主机; //now url === "http:://***.com"结帐::【参考方案2】:

基于 WebKit 的浏览器、Firefox 21 版和当前版本的 Internet Explorer(IE 10 和 11)实现 location.origin

location.origin 包括 protocoldomain 和可选的 URL 的 port

例如,URL http://www.sitename.com/article/2009/09/14/this-is-an-article/location.originhttp://www.sitename.com

要定位不支持 location.origin 的浏览器,请使用以下简洁的 polyfill:

if (typeof location.origin === 'undefined')
    location.origin = location.protocol + '//' + location.host;

【讨论】:

window.location.hostname 将丢失端口号,因此请使用window.location.host。因此,包括斜杠在内的完整“基本名称”将是:window.location.protocol+"//"+window.location.host + "/"; 实际上,window.location.hostname 仍然有用,如果像我一样,您需要提供不同的端口号。【参考方案3】:

不需要使用jQuery,只需使用

location.hostname

【讨论】:

谢谢 - 不过,我不能将它与字符串一起使用,可以吗?我的理解是,这仅适用于文档 URL。 这将不包括协议和端口。【参考方案4】:

没有理由进行拆分以从作为链接的字符串中获取路径、主机名等。你只需要使用一个链接

//create a new element link with your link
var a = document.createElement("a");
a.href="http://www.sitename.com/article/2009/09/14/this-is-an-article/";

//hide it from view when it is added
a.style.display="none";

//add it
document.body.appendChild(a);

//read the links "features"
alert(a.protocol);
alert(a.hostname)
alert(a.pathname)
alert(a.port);
alert(a.hash);

//remove it
document.body.removeChild(a);

您可以通过 jQuery 附加元素并读取其属性轻松地做到这一点。

更新:现在有new URL() 简化了它

const myUrl = new URL("https://www.example.com:3000/article/2009/09/14/this-is-an-article/#m123")

const parts = ['protocol', 'hostname', 'pathname', 'port', 'hash'];

parts.forEach(key => console.log(key, myUrl[key]))

【讨论】:

当你在几个字节中展示了如何在没有 jQuery 的情况下添加 50K 的 jQuery 时,为什么还要添加 50K? 因为发帖人说他们使用的是 jQuery。 啊,是的,很公平。虽然如此简单,但我认为使用 jQuery 会添加的额外抽象层没有任何价值。 我们假设整个站点在 jqUERY 上运行,在这种情况下,kquery 确实可以简化事情。 Ewww...这不是最好的方法...如果从 window.location.href 中提取,请使用 window.location。否则,请使用正则表达式。【参考方案5】:
var host = location.protocol + '//' + location.host + '/';

【讨论】:

这应该被认为是正确的答案 - 它保留了协议【参考方案6】:

好吧,URL API object 避免手动拆分和构造 url。

 let url = new URL('https://***.com/questions/1420881');
 alert(url.origin);

【讨论】:

【参考方案7】:
String.prototype.url = function() 
  const a = $('<a />').attr('href', this)[0];
  // or if you are not using jQuery ??
  // const a = document.createElement('a'); a.setAttribute('href', this);
  let origin = a.protocol + '//' + a.hostname;
  if (a.port.length > 0) 
    origin = `$origin:$a.port`;
  
  const host, hostname, pathname, port, protocol, search, hash = a;
  return origin, host, hostname, pathname, port, protocol, search, hash;


然后:

'http://mysite:5050/pke45#23'.url()
 //OUTPUT : host: "mysite:5050", hostname: "mysite", pathname: "/pke45", port: "5050", protocol: "http:",hash:"#23",origin:"http://mysite:5050"

根据您的要求,您需要:

 'http://mysite:5050/pke45#23'.url().origin

评论 07-2017 : 它也可以更优雅&具有更多功能

const parseUrl = (string, prop) =>  
  const a = document.createElement('a'); 
  a.setAttribute('href', string);
  const host, hostname, pathname, port, protocol, search, hash = a;
  const origin = `$protocol//$hostname$port.length ? `:$port`:''`;
  return prop ? eval(prop) : origin, host, hostname, pathname, port, protocol, search, hash

然后

parseUrl('http://mysite:5050/pke45#23')
// origin: "http://mysite:5050", host: "mysite:5050", hostname: "mysite", pathname: "/pke45", port: "5050"…


parseUrl('http://mysite:5050/pke45#23', 'origin')
// "http://mysite:5050"

酷!

【讨论】:

【参考方案8】:

如果您使用 jQuery,这是一种在 javascript 中操作元素而不将它们添加到 DOM 的好方法:

var myAnchor = $("<a />");

//set href    
myAnchor.attr('href', 'http://example.com/path/to/myfile')

//your link's features
var hostname = myAnchor.attr('hostname'); // http://example.com
var pathname = myAnchor.attr('pathname'); // /path/to/my/file
//...etc

【讨论】:

我认为应该是myAnchor.prop('hostname')。我猜 jQuery 在过去 5 年里发生了变化……感谢您的回答!【参考方案9】:

Douglas Crockford 的正则表达式规则是从 URL 的字符串表示中获取基本值的一种轻巧但完整的方法:

var yourUrl = "http://www.sitename.com/article/2009/09/14/this-is-an-article/";
var parse_url = /^(?:([A-Za-z]+):)?(\/0,3)([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
var parts = parse_url.exec( yourUrl );
var result = parts[1]+':'+parts[2]+parts[3]+'/' ;

如果您正在寻找更强大的 URL 操作工具包,请尝试 URI.js 它支持 getter、setter、url 规范化等,所有这些都带有一个不错的可链接 api。

如果您正在寻找一个 jQuery 插件,那么 jquery.url.js 应该可以帮助您

正如@epascarello 建议的那样,一个更简单的方法是使用锚元素。这样做的缺点是您必须创建一个 DOM 元素。然而,这可以被缓存在一个闭包中并被多个 url 重用:

var parseUrl = (function () 
  var a = document.createElement('a');
  return function (url) 
    a.href = url;
    return 
      host: a.host,
      hostname: a.hostname,
      pathname: a.pathname,
      port: a.port,
      protocol: a.protocol,
      search: a.search,
      hash: a.hash
    ;
  
)();

像这样使用它:

paserUrl('http://google.com');

【讨论】:

【参考方案10】:

如果您是从 window.location.href(地址栏)中提取信息,则使用此代码获取http://www.sitename.com/

var loc = location;
var url = loc.protocol + "//" + loc.host + "/";

如果您有一个字符串 str,它是一个任意 URL(不是 window.location.href),那么使用正则表达式:

var url = str.match(/^(([a-z]+:)?(\/\/)?[^\/]+\/).*$/)[1];

我和宇宙中的每个人一样,讨厌阅读正则表达式,所以我会用英语对其进行分解:

查找零个或多个字母字符后跟冒号(协议,可以省略) 后跟 //(也可以省略) 后跟除 /(主机名和端口)以外的任何字符 后跟/ 后跟任何内容(路径,减去开头的 /)。

无需创建 DOM 元素或做任何疯狂的事情。

【讨论】:

【参考方案11】:

您可以使用以下代码获取当前 URL 的不同参数

alert("document.URL : "+document.URL);
alert("document.location.href : "+document.location.href);
alert("document.location.origin : "+document.location.origin);
alert("document.location.hostname : "+document.location.hostname);
alert("document.location.host : "+document.location.host);
alert("document.location.pathname : "+document.location.pathname);

【讨论】:

【参考方案12】:

我使用一个简单的正则表达式从 url 中提取主机:

function get_host(url)
    return url.replace(/^((\w+:)?\/\/[^\/]+\/?).*$/,'$1');

并像这样使用它

var url = 'http://www.sitename.com/article/2009/09/14/this-is-an-article/'
var host = get_host(url);

请注意,如果url 不以/ 结尾,则host 不会以/ 结尾。

这里有一些测试:

describe('get_host', function()
    it('should return the host', function()
        var url = 'http://www.sitename.com/article/2009/09/14/this-is-an-article/';
        assert.equal(get_host(url),'http://www.sitename.com/');
    );
    it('should not have a / if the url has no /', function()
        var url = 'http://www.sitename.com';
        assert.equal(get_host(url),'http://www.sitename.com');
    );
    it('should deal with https', function()
        var url = 'https://www.sitename.com/article/2009/09/14/this-is-an-article/';
        assert.equal(get_host(url),'https://www.sitename.com/');
    );
    it('should deal with no protocol urls', function()
        var url = '//www.sitename.com/article/2009/09/14/this-is-an-article/';
        assert.equal(get_host(url),'//www.sitename.com/');
    );
    it('should deal with ports', function()
        var url = 'http://www.sitename.com:8080/article/2009/09/14/this-is-an-article/';
        assert.equal(get_host(url),'http://www.sitename.com:8080/');
    );
    it('should deal with localhost', function()
        var url = 'http://localhost/article/2009/09/14/this-is-an-article/';
        assert.equal(get_host(url),'http://localhost/');
    );
    it('should deal with numeric ip', function()
        var url = 'http://192.168.18.1/article/2009/09/14/this-is-an-article/';
        assert.equal(get_host(url),'http://192.168.18.1/');
    );
);

【讨论】:

【参考方案13】:

一个好的方法是使用 JavaScript 原生 api URL 对象。这提供了许多有用的 url 部分。

例如:

const url = 'https://***.com/questions/1420881/how-to-extract-base-url-from-a-string-in-javascript'

const urlObject = new URL(url);

console.log(urlObject);


// RESULT: 
//________________________________
hash: "",
host: "***.com",
hostname: "***.com",
href: "https://***.com/questions/1420881/how-to-extract-base-url-from-a-string-in-javascript",
origin: "https://***.com",
password: "",
pathname: "/questions/1420881/how-to-extract-base-url-from-a-string-in-javaript",
port: "",
protocol: "https:",
search: "",
searchParams: [object URLSearchParams]
... + some other methods

正如您在此处看到的,您可以访问所需的任何内容。

例如:console.log(urlObject.host); // "***.com"

URL的文档

【讨论】:

【参考方案14】:
function getBaseURL() 
    var url = location.href;  // entire url including querystring - also: window.location.href;
    var baseURL = url.substring(0, url.indexOf('/', 14));


    if (baseURL.indexOf('http://localhost') != -1) 
        // Base Url for localhost
        var url = location.href;  // window.location.href;
        var pathname = location.pathname;  // window.location.pathname;
        var index1 = url.indexOf(pathname);
        var index2 = url.indexOf("/", index1 + 1);
        var baseLocalUrl = url.substr(0, index2);

        return baseLocalUrl + "/";
    
    else 
        // Root Url for domain name
        return baseURL + "/";
    


然后你可以这样使用它...

var str = 'http://en.wikipedia.org/wiki/Knopf?q=1&t=2';
var url = str.toUrl();

url 的值将是...


"original":"http://en.wikipedia.org/wiki/Knopf?q=1&t=2",<br/>"protocol":"http:",
"domain":"wikipedia.org",<br/>"host":"en.wikipedia.org",<br/>"relativePath":"wiki"

“var url”也包含两个方法。

var paramQ = url.getParameter('q');

在这种情况下,paramQ 的值为 1。

var allParameters = url.getParameters();

allParameters 的值将只是参数名称。

["q","t"]

在 IE、chrome 和 firefox 上测试。

【讨论】:

我想我错过了什么... toUrl 来自哪里?【参考方案15】:

不必考虑window.location.protocol和window.location.origin,并且可能缺少指定的端口号等,只需获取第三个“/”之前的所有内容:

// get nth occurrence of a character c in the calling string
String.prototype.nthIndex = function (n, c) 
    var index = -1;
    while (n-- > 0) 
        index++;
        if (this.substring(index) == "") return -1; // don't run off the end
        index += this.substring(index).indexOf(c);
    
    return index;


// get the base URL of the current page by taking everything up to the third "/" in the URL
function getBaseURL() 
    return document.URL.substring(0, document.URL.nthIndex(3,"/") + 1);

【讨论】:

【参考方案16】:

这行得通:

location.href.split(location.pathname)[0];

【讨论】:

location.pathname = '/'的情况下失败【参考方案17】:

您可以使用正则表达式:

/(http:\/\/)?(www)[^\/]+\//i

合适吗?

【讨论】:

嗯,从我有限的正则表达式技能来看,这看起来至少很接近。我将在问题中添加更多信息,看看我是否可以帮助缩小最佳正则表达式的范围。 我最终在字符串上使用 .split('/') 只是因为它对我来说是一个更简单的解决方案。不过,感谢您的帮助! https 网址?主机名不以 www 开头?为什么还要捕获 www? 我不知道,OP问如何捕捉一个url,在他的例子中有http & www。【参考方案18】:

为了获取任何 url 的来源,包括网站内的路径 (/my/path) 或无模式 (//example.com/my/path) 或完整 (http://example.com/my/path),我组合了一个快速函数。

在下面的 sn-p 中,所有三个调用都应记录 https://stacksnippets.net

function getOrigin(url)

  if(/^\/\//.test(url))
   // no scheme, use current scheme, extract domain
    url = window.location.protocol + url;
  
  else if(/^\//.test(url))
   // just path, use whole origin
    url = window.location.origin + url;
  
  return url.match(/^([^/]+\/\/[^/]+)/)[0];


console.log(getOrigin('https://stacksnippets.net/my/path'));
console.log(getOrigin('//stacksnippets.net/my/path'));
console.log(getOrigin('/my/path'));

【讨论】:

【参考方案19】:

这对我有用:

var getBaseUrl = function (url) 
  if (url) 
    var parts = url.split('://');
    
    if (parts.length > 1) 
      return parts[0] + '://' + parts[1].split('/')[0] + '/';
     else 
      return parts[0].split('/')[0] + '/';
    
  
;

【讨论】:

【参考方案20】:
var tilllastbackslashregex = new RegExp(/^.*\//);
baseUrl = tilllastbackslashregex.exec(window.location.href);

window.location.href 从浏览器地址栏给出当前 url 地址

它可以是https://***.com/abc/xyz 或https://www.google.com/search?q=abctilllastbackslashregex.exec() 之类的任何东西,运行正则表达式并重新调整匹配的字符串直到最后一个反斜杠,即分别为https://***.com/abc/ 或https://www.google.com/

【讨论】:

请添加简要说明。 来自审核队列:我可以请求您在源代码周围添加一些上下文。仅代码的答案很难理解。如果您可以在帖子中添加更多信息,这将对提问者和未来的读者都有帮助。【参考方案21】:

实施:

const getOriginByUrl = url => url.split('/').slice(0, 3).join('/');

测试:

getOriginByUrl('http://www.sitename.com:3030/article/2009/09/14/this-is-an-article?lala=kuku');

结果:

'http://www.sitename.com:3030'

【讨论】:

以上是关于如何从 JavaScript 中的字符串中提取基本 URL?的主要内容,如果未能解决你的问题,请参考以下文章

如何从javascript中的rgb字符串中提取颜色值[重复]

JavaScript中如何提取字符串?

JavaScript 中的 Promises/Fetch:如何从文本文件中提取文本

如何从 Javascript 中的 URL 中提取 GET 参数? [复制]

从Javascript中的URL中提取一部分[重复]

如何使用javascript或jquery从字符串中提取html标签的内容? [复制]