如何在javascript中将URL解析为主机名和路径?

fre*_*ara 345 javascript url

我想拿个字符串

var a = "http://example.com/aa/bb/"
Run Code Online (Sandbox Code Playgroud)

并将其处理成一个对象

a.hostname == "example.com"
Run Code Online (Sandbox Code Playgroud)

a.pathname == "/aa/bb"
Run Code Online (Sandbox Code Playgroud)

fre*_*ara 356

var getLocation = function(href) {
    var l = document.createElement("a");
    l.href = href;
    return l;
};
var l = getLocation("http://example.com/path");
console.debug(l.hostname)
>> "example.com"
console.debug(l.pathname)
>> "/path"
Run Code Online (Sandbox Code Playgroud)

  • 应该注意的是,虽然这可能有助于/回答原始海报,但这个答案只适用于在浏览器中进行JS工作的人,因为它依赖于DOM来完成其工作. (62认同)
  • 如果href是相对的,则在IE中不起作用.l.hostname将为空.如果您只提供完整的URL,那么这将有效. (25认同)
  • 您确定这是一个跨浏览器兼容的解决方案吗? (14认同)
  • 即使使用绝对URL,IE(在IE 11中测试)的行为与Chrome和Firefox的行为也不同.IE的`pathname`删除了前导斜杠,而其他浏览器则没有.所以你最终会得到`/ path`或`path`,具体取决于你的浏览器. (7认同)
  • 简洁的另一个例子,以及独创性. (4认同)

rvi*_*hne 334

现代方式:

new URL("http://example.com/aa/bb/")
Run Code Online (Sandbox Code Playgroud)

返回与属性的对象hostnamepathname,连同其他几个人.

第一个参数是相对或绝对URL; 如果它是相对的,那么你需要指定第二个参数(基本URL).例如,对于相对于当前页面的URL:

new URL("/aa/bb/", location)
Run Code Online (Sandbox Code Playgroud)

除了浏览器之外,从v7开始,此API也可在Node.js中使用require('url').URL.

  • 实验技术:IE不支持这个!https://developer.mozilla.org/en-US/docs/Web/API/URL/URL#Browser_compatibility (51认同)
  • @cwouter:它确实在Edge中工作,它取代了IE (9认同)
  • 太好了!相对URL打破了它... :(`new URL('/ stuff?foo = bar#baz')` - >`SyntaxError:无法构造'URL':无效的URL (5认同)
  • 这是方法,边缘已经是3个版本,所以它没关系 (4认同)
  • JavaScript没有内置的方法来解析在浏览器或服务器上运行的URL是非常可悲的...... (4认同)
  • @lakenen:我在答案中添加了修复程序. (3认同)
  • @justingordon:`URL`类是Web标准,因此不需要非浏览器来实现它.但是,最近版本的Nodej确实提供了相同的库,[`require('url').urL`](https://nodejs.org/api/url.html#url_the_whatwg_url_api) (3认同)
  • @Skitterm 事实确实如此,这非常讽刺。 (3认同)

Jos*_*ter 287

在这里找到:https://gist.github.com/jlong​​/2428561

var parser = document.createElement('a');
parser.href = "http://example.com:3000/pathname/?search=test#hash";

parser.protocol; // => "http:"
parser.host;     // => "example.com:3000"
parser.hostname; // => "example.com"
parser.port;     // => "3000"
parser.pathname; // => "/pathname/"
parser.hash;     // => "#hash"
parser.search;   // => "?search=test"
parser.origin;   // => "http://example.com:3000"
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果您只想获取当前浏览器位置的已解析部分,则前两行将变为`parser = location;`并且以下所有行都有效.刚刚在Chrome和IE9中尝试过它. (11认同)
  • 另请注意,`pathname`不包括IE中的前导斜杠.去搞清楚.:d (9认同)
  • 对于IE,请使用"/"+ parser.pathname (2认同)
  • 不适用于IE9中的相对URL (2认同)

Rem*_*ems 102

这是一个使用模仿a标记行为的正则表达式的简单函数.

优点

  • 可预测的行为(没有跨浏览器问题)
  • 不需要DOM
  • 它真的很短.

缺点

  • 正则表达式有点难以阅读

-

function getLocation(href) {
    var match = href.match(/^(https?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/);
    return match && {
        href: href,
        protocol: match[1],
        host: match[2],
        hostname: match[3],
        port: match[4],
        pathname: match[5],
        search: match[6],
        hash: match[7]
    }
}
Run Code Online (Sandbox Code Playgroud)

-

getLocation("http://example.com/");
/*
{
    "protocol": "http:",
    "host": "example.com",
    "hostname": "example.com",
    "port": undefined,
    "pathname": "/"
    "search": "",
    "hash": "",
}
*/

getLocation("http://example.com:3000/pathname/?search=test#hash");
/*
{
    "protocol": "http:",
    "host": "example.com:3000",
    "hostname": "example.com",
    "port": "3000",
    "pathname": "/pathname/",
    "search": "?search=test",
    "hash": "#hash"
}
*/
Run Code Online (Sandbox Code Playgroud)

编辑:

这是正则表达式的细分

var reURLInformation = new RegExp([
    '^(https?:)//', // protocol
    '(([^:/?#]*)(?::([0-9]+))?)', // host (hostname and port)
    '(/{0,1}[^?#]*)', // pathname
    '(\\?[^#]*|)', // search
    '(#.*|)$' // hash
].join(''));
var match = href.match(reURLInformation);
Run Code Online (Sandbox Code Playgroud)

  • 不适用于任何相对URL.在制作正则表达式时,您是否遵循RFC-3986?> getLocation("// example.com/"); null> getLocation("/ pathname /?search"); null> getLocation("/ pathname /"); null> getLocation("relative"); 空值 (3认同)
  • 我喜欢这不使用DOM,但gregers有一个好点.如果这可以处理相对路径会很好.它需要使用window.location(一个元素)来填充空白并添加代码.在这种情况下,该方法将变得虚伪.除非有替代方案,否则不能确定如何完美地解决这个问题. (2认同)
  • 如果有人需要解析相对 URL,这里是更新的正则表达式: /^(?:(https?\:)\/\/)?(([^:\/?#]*)(?:\:([0 -9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/ (2认同)

Pet*_*ham 63

var loc = window.location;  // => "http://example.com:3000/pathname/?search=test#hash"
Run Code Online (Sandbox Code Playgroud)

返回currentUrl.

如果要将自己的字符串作为url传递(在IE11中不起作用):

var loc = new URL("http://example.com:3000/pathname/?search=test#hash")
Run Code Online (Sandbox Code Playgroud)

然后你可以解析它:

loc.protocol; // => "http:"
loc.host;     // => "example.com:3000"
loc.hostname; // => "example.com"
loc.port;     // => "3000"
loc.pathname; // => "/pathname/"
loc.hash;     // => "#hash"
loc.search;   // => "?search=test"
Run Code Online (Sandbox Code Playgroud)


Cla*_*aus 59

freddiefujiwara的答案非常好,但我还需要支持Internet Explorer中的相对URL.我提出了以下解决方案:

function getLocation(href) {
    var location = document.createElement("a");
    location.href = href;
    // IE doesn't populate all link properties when setting .href with a relative URL,
    // however .href will return an absolute URL which then can be used on itself
    // to populate these additional fields.
    if (location.host == "") {
      location.href = location.href;
    }
    return location;
};
Run Code Online (Sandbox Code Playgroud)

现在用它来获取所需的属性:

var a = getLocation('http://example.com/aa/bb/');
document.write(a.hostname);
document.write(a.pathname);
Run Code Online (Sandbox Code Playgroud)

JSFiddle示例:http://jsfiddle.net/6AEAB/

  • 这应该是公认的答案.非常巧妙地使用相对于绝对URL处理.+1 (4认同)
  • 这很好用,但我有一个更新,我希望能帮助其他人.我正在使用它来检查postMessage请求的原点,当端口是默认端口(80或443)时,它不会附加到路径上.我在创建URL时有条件地检查过:`var locationHost =(location.port!=='80'&& location.port!=='443')?location.host:location.hostname;``var locationOrigin = location.protocol +'//'+ locationHost;` (3认同)
  • 我在其他地方就这个解决方案的一个更流行的变体做了这个评论,但由于这是我最喜欢的解决方案,我想在这里重复一遍.在IE11中,在href中具有用户名将导致所有这些属性读取引发安全性错误.示例:"http://www.example.com"将正常工作.但是"http://username@www.example.com"或"http:// username:password@www.example.com"将尝试引用锚元素的其他属性之一(例如:hash)失败并引发一个令人讨厌的错误. (2认同)

Rex*_*x M 17

js-uri(可在Google Code上获得)获取字符串URL并从中解析URI对象:

var some_uri = new URI("http://www.example.com/foo/bar");

alert(some_uri.authority); // www.example.com
alert(some_uri);           // http://www.example.com/foo/bar

var blah      = new URI("blah");
var blah_full = blah.resolve(some_uri);
alert(blah_full);         // http://www.example.com/foo/blah
Run Code Online (Sandbox Code Playgroud)


sve*_*tka 12

简单的正则表达怎么样?

url = "http://www.example.com/path/to/somwhere";
urlParts = /^(?:\w+\:\/\/)?([^\/]+)(.*)$/.exec(url);
hostname = urlParts[1]; // www.example.com
path = urlParts[2]; // /path/to/somwhere
Run Code Online (Sandbox Code Playgroud)


Bia*_*bba 9

这是我从https://gist.github.com/1847816复制的版本,但重写后更容易阅读和调试.将锚数据复制到另一个名为"result"的变量的目的是因为锚数据非常长,因此将有限数量的值复制到结果将有助于简化结果.

/**
 * See: https://gist.github.com/1847816
 * Parse a URI, returning an object similar to Location
 * Usage: var uri = parseUri("hello?search#hash")
 */
function parseUri(url) {

  var result = {};

  var anchor = document.createElement('a');
  anchor.href = url;

  var keys = 'protocol hostname host pathname port search hash href'.split(' ');
  for (var keyIndex in keys) {
    var currentKey = keys[keyIndex]; 
    result[currentKey] = anchor[currentKey];
  }

  result.toString = function() { return anchor.href; };
  result.requestUri = result.pathname + result.search;  
  return result;

}
Run Code Online (Sandbox Code Playgroud)


A. *_*net 7

今天我遇到了这个问题,我发现:URL - MDN Web API

var url = new URL("http://test.example.com/dir/subdir/file.html#hash");
Run Code Online (Sandbox Code Playgroud)

这个回报:

{ hash:"#hash", host:"test.example.com", hostname:"test.example.com", href:"http://test.example.com/dir/subdir/file.html#hash", origin:"http://test.example.com", password:"", pathname:"/dir/subdir/file.html", port:"", protocol:"http:", search: "", username: "" }
Run Code Online (Sandbox Code Playgroud)

希望我的第一个贡献可以帮到你!

  • 是的,但是顶级的人只是在2017年更新了他,我在2016年发布了它. (2认同)

Nik*_*lay 7

function parseUrl(url) {
    var m = url.match(/^(([^:\/?#]+:)?(?:\/\/((?:([^\/?#:]*):([^\/?#:]*)@)?([^\/?#:]*)(?::([^\/?#:]*))?)))?([^?#]*)(\?[^#]*)?(#.*)?$/),
        r = {
            hash: m[10] || "",                   // #asd
            host: m[3] || "",                    // localhost:257
            hostname: m[6] || "",                // localhost
            href: m[0] || "",                    // http://username:password@localhost:257/deploy/?asd=asd#asd
            origin: m[1] || "",                  // http://username:password@localhost:257
            pathname: m[8] || (m[1] ? "/" : ""), // /deploy/
            port: m[7] || "",                    // 257
            protocol: m[2] || "",                // http:
            search: m[9] || "",                  // ?asd=asd
            username: m[4] || "",                // username
            password: m[5] || ""                 // password
        };
    if (r.protocol.length == 2) {
        r.protocol = "file:///" + r.protocol.toUpperCase();
        r.origin = r.protocol + "//" + r.host;
    }
    r.href = r.origin + r.pathname + r.search + r.hash;
    return r;
};
parseUrl("http://username:password@localhost:257/deploy/?asd=asd#asd");
Run Code Online (Sandbox Code Playgroud)

它适用于绝对和相对网址


acd*_*ior 6

跨浏览器URL解析,解决IE 6,7,8和9 的相对路径问题:

function ParsedUrl(url) {
    var parser = document.createElement("a");
    parser.href = url;

    // IE 8 and 9 dont load the attributes "protocol" and "host" in case the source URL
    // is just a pathname, that is, "/example" and not "http://domain.com/example".
    parser.href = parser.href;

    // IE 7 and 6 wont load "protocol" and "host" even with the above workaround,
    // so we take the protocol/host from window.location and place them manually
    if (parser.host === "") {
        var newProtocolAndHost = window.location.protocol + "//" + window.location.host;
        if (url.charAt(1) === "/") {
            parser.href = newProtocolAndHost + url;
        } else {
            // the regex gets everything up to the last "/"
            // /path/takesEverythingUpToAndIncludingTheLastForwardSlash/thisIsIgnored
            // "/" is inserted before because IE takes it of from pathname
            var currentFolder = ("/"+parser.pathname).match(/.*\//)[0];
            parser.href = newProtocolAndHost + currentFolder + url;
        }
    }

    // copies all the properties to this object
    var properties = ['host', 'hostname', 'hash', 'href', 'port', 'protocol', 'search'];
    for (var i = 0, n = properties.length; i < n; i++) {
      this[properties[i]] = parser[properties[i]];
    }

    // pathname is special because IE takes the "/" of the starting of pathname
    this.pathname = (parser.pathname.charAt(0) !== "/" ? "/" : "") + parser.pathname;
}
Run Code Online (Sandbox Code Playgroud)

用法(这里演示JSFiddle):

var myUrl = new ParsedUrl("http://www.example.com:8080/path?query=123#fragment");
Run Code Online (Sandbox Code Playgroud)

结果:

{
    hash: "#fragment"
    host: "www.example.com:8080"
    hostname: "www.example.com"
    href: "http://www.example.com:8080/path?query=123#fragment"
    pathname: "/path"
    port: "8080"
    protocol: "http:"
    search: "?query=123"
}
Run Code Online (Sandbox Code Playgroud)


Kin*_*tes 5

对于那些寻找适用于IE,Firefox和Chrome的现代解决方案的人:

这些使用超链接元素的解决方案在chrome中都不会起作用.如果将无效(或空白)URL传递给chrome,它将始终返回调用脚本的主机.因此,在IE中,您将获得空白,而在Chrome中,您将获得localhost(或其他).

如果您试图查看推荐人,这是欺骗性的.您需要确保您获得的主机位于原始网址中以处理此问题:

    function getHostNameFromUrl(url) {
        // <summary>Parses the domain/host from a given url.</summary>
        var a = document.createElement("a");
        a.href = url;

        // Handle chrome which will default to domain where script is called from if invalid
        return url.indexOf(a.hostname) != -1 ? a.hostname : '';
    }
Run Code Online (Sandbox Code Playgroud)