【问题标题】:How to extract base URL from a string in JavaScript?如何从 JavaScript 中的字符串中提取基本 URL?
【发布时间】: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 收集这些信息。

【问题讨论】:

标签: javascript regex string url


【解决方案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:://stackoverflow.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://stackoverflow.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://stackoverflow.com/questions/1420881/how-to-extract-base-url-from-a-string-in-javascript'
              
              const urlObject = new URL(url);
              
              console.log(urlObject);
              
              
              // RESULT: 
              //________________________________
              hash: "",
              host: "stackoverflow.com",
              hostname: "stackoverflow.com",
              href: "https://stackoverflow.com/questions/1420881/how-to-extract-base-url-from-a-string-in-javascript",
              origin: "https://stackoverflow.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); // "stackoverflow.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://stackoverflow.com/abc/xyzhttps://www.google.com/search?q=abctilllastbackslashregex.exec() 之类的任何东西,运行正则表达式并重新调整匹配的字符串直到最后一个反斜杠,即分别为https://stackoverflow.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'
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2014-12-15
                        • 1970-01-01
                        • 2020-03-22
                        • 2012-02-11
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多