Como faço para analisar um URL em hostname e caminho em javascript?

Eu gostaria de pegar uma string

var a = "http://example.com/aa/bb/" 

e processá-lo em um object tal que

 a.hostname == "example.com" 

e

 a.pathname == "/aa/bb" 

 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" 

encontrado aqui: 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" 

O jeito moderno:

 new URL("http://example.com/aa/bb/") 

Retorna um object com propriedades hostname e pathname , junto com alguns outros .

O primeiro argumento é um URL relativo ou absoluto; Se for relativo, então você precisa especificar o segundo argumento (o URL base). Por exemplo, para um URL relativo à página atual:

 new URL("/aa/bb/", location) 

Além dos navegadores, essa API também está disponível no Node.js desde a v7, através do require('url').URL .

Aqui está uma function simples usando um regexp que imita o comportamento da tag.

Prós

  • comportamento previsível (sem problemas entre navegadores)
  • não precisa do DOM
  • é muito curto.

Contras

  • O regexp é um pouco difícil de ler

 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] } } 

 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" } */ 

EDITAR:

Aqui está um resumo da expressão regular

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

A resposta do freddiefujiwara é muito boa, mas eu também precisava suportar URLs relativas no Internet Explorer. Eu criei a seguinte solução:

 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; }; 

Agora use-o para obter as propriedades necessárias:

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

Exemplo de JSFiddle: http://jsfiddle.net/6AEAB/

 var loc = window.location; // => "http://example.com:3000/pathname/?search=test#hash" 

retorna o currentUrl.

Se você quiser passar sua própria string como url ( não funciona no IE11 ):

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

Então você pode analisar como:

 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" 

js-uri (disponível no Google Code) pega uma URL de string e resolve um object URI dela:

 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 

E quanto à simples expressão regular?

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

Aqui está uma versão que copiei de https://gist.github.com/1847816 , mas que foi reescrita para facilitar a leitura e a debugging. A finalidade de copiar os dados da âncora para outra variável denominada “resultado” é porque os dados da âncora são bastante longos e, portanto, copiar um número limitado de valores para o resultado ajudará a simplificar o resultado.

 /** * 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; } 

Para quem procura uma solução moderna que funcione no IE, Firefox e Chrome:

Nenhuma dessas soluções que usam um elemento de hiperlink funcionará da mesma maneira no chrome. Se você passar um URL inválido (ou em branco) para o chrome, ele sempre retornará o host de onde o script é chamado. Então, no IE, você ficará em branco, enquanto no Chrome você terá o host local (ou qualquer outro).

Se você está tentando olhar para o referenciador, isso é enganoso. Você vai querer ter certeza de que o host que você recebeu de volta estava no URL original para lidar com isso:

  function getHostNameFromUrl(url) { // Parses the domain/host from a given url. 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 : ''; } 

Você também pode usar a function parse_url() do projeto php.js.

Código:

 parse_url('http://username:password@hostname/path?arg=value#anchor'); 

Resultado:

 { scheme: 'http', host: 'hostname', user: 'username', pass: 'password', path: '/path', query: 'arg=value', fragment: 'anchor' } 

A análise de URL entre navegadores , trabalha em torno do problema de caminho relativo para o IE 6, 7, 8 e 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; } 

Uso ( demo JSFiddle aqui ):

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

Resultado:

 { 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" } 

O jeito AngularJS – mexer aqui: http://jsfiddle.net/PT5BG/4/

 < !DOCTYPE html>   Parse URL using AngularJS   

Parse URL using AngularJS

url:
  • href = {{parser.href}}
  • protocol = {{parser.protocol}}
  • host = {{parser.host}}
  • hostname = {{parser.hostname}}
  • port = {{parser.port}}
  • pathname = {{parser.pathname}}
  • hash = {{parser.hash}}
  • search = {{parser.search}}

hoje eu encontrei este problema e encontrei: URL – APIs da Web MDN

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

Esse retorno:

 { 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: "" } 

Espero que minha primeira contribuição te ajude!

Solução simples e robusta usando o padrão de módulo. Isso inclui uma correção para o IE, em que o pathname do pathname nem sempre tem uma barra de avanço ( / ).

Eu criei um Gist junto com um JSFiddle que oferece um analisador mais dynamic. Eu recomendo que você verifique e forneça feedback.

 var URLParser = (function (document) { var PROPS = 'protocol hostname host pathname port search hash href'.split(' '); var self = function (url) { this.aEl = document.createElement('a'); this.parse(url); }; self.prototype.parse = function (url) { this.aEl.href = url; if (this.aEl.host == "") { this.aEl.href = this.aEl.href; } PROPS.forEach(function (prop) { switch (prop) { case 'hash': this[prop] = this.aEl[prop].substr(1); break; default: this[prop] = this.aEl[prop]; } }, this); if (this.pathname.indexOf('/') !== 0) { this.pathname = '/' + this.pathname; } this.requestUri = this.pathname + this.search; }; self.prototype.toObj = function () { var obj = {}; PROPS.forEach(function (prop) { obj[prop] = this[prop]; }, this); obj.requestUri = this.requestUri; return obj; }; self.prototype.toString = function () { return this.href; }; return self; })(document); 

Demonstração

 var URLParser = (function(document) { var PROPS = 'protocol hostname host pathname port search hash href'.split(' '); var self = function(url) { this.aEl = document.createElement('a'); this.parse(url); }; self.prototype.parse = function(url) { this.aEl.href = url; if (this.aEl.host == "") { this.aEl.href = this.aEl.href; } PROPS.forEach(function(prop) { switch (prop) { case 'hash': this[prop] = this.aEl[prop].substr(1); break; default: this[prop] = this.aEl[prop]; } }, this); if (this.pathname.indexOf('/') !== 0) { this.pathname = '/' + this.pathname; } this.requestUri = this.pathname + this.search; }; self.prototype.toObj = function() { var obj = {}; PROPS.forEach(function(prop) { obj[prop] = this[prop]; }, this); obj.requestUri = this.requestUri; return obj; }; self.prototype.toString = function() { return this.href; }; return self; })(document); /* Main */ var out = document.getElementById('out'); var urls = [ 'https://www.example.org:5887/foo/bar?a=1&b=2#section-1', 'ftp://www.files.com:22/folder?id=7' ]; var parser = new URLParser(); urls.forEach(function(url) { parser.parse(url); println(out, JSON.stringify(parser.toObj(), undefined, ' '), 0, '#0000A7'); }); /* Utility functions */ function print(el, text, bgColor, fgColor) { var span = document.createElement('span'); span.innerHTML = text; span.style['backgroundColor'] = bgColor || '#FFFFFF'; span.style['color'] = fgColor || '#000000'; el.appendChild(span); } function println(el, text, bgColor, fgColor) { print(el, text, bgColor, fgColor); el.appendChild(document.createElement('br')); } 
 body { background: #444; } span { background-color: #fff; border: thin solid black; display: inline-block; } #out { display: block; font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif; font-size: 12px; white-space: pre; } 
 

Use https://www.npmjs.com/package/uri-parse-lib para este

 var t = parserURI("http://user:pass@example.com:8080/directory/file.ext?query=1&next=4&sed=5#anchor"); 

Pare de reinventar a roda. Use https://github.com/medialize/URI.js/

 var uri = new URI("http://example.org:80/foo/hello.html"); // get host uri.host(); // returns string "example.org:80" // set host uri.host("example.org:80"); 

Apenas use a biblioteca url.js (para web e node.js).

https://github.com/websanova/js-url

 url: http://example.com?param=test#param=again url('?param'); // test url('#param'); // again url('protocol'); // http url('port'); // 80 url('domain'); // example.com url('tld'); // com etc... 
 function parseUrl(url) { var m = url.match(/^(([^:\/?#]+:)?(?:\/\/(([^\/?#:]*)(?::([^\/?#:]*))?)))?([^?#]*)(\?[^#]*)?(#.*)?$/), r = { hash: m[8] || "", // #asd host: m[3] || "", // localhost:257 hostname: m[4] || "", // localhost href: m[0] || "", // http://localhost:257/deploy/?asd=asd#asd origin: m[1] || "", // http://localhost:257 pathname: m[6] || (m[1] ? "/" : ""), // /deploy/ port: m[5] || "", // 257 protocol: m[2] || "", // http: search: m[7] || "" // ?asd=asd }; 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 m && r; }; 

Funciona com URLs absolutas e relativas

Por que não usá-lo?

  $scope.get_location=function(url_str){ var parser = document.createElement('a'); parser.href =url_str;//"http://example.com:3000/pathname/?search=test#hash"; var info={ protocol:parser.protocol, hostname:parser.hostname, // => "example.com" port:parser.port, // => "3000" pathname:parser.pathname, // => "/pathname/" search:parser.search, // => "?search=test" hash:parser.hash, // => "#hash" host:parser.host, // => "example.com:3000" } return info; } alert( JSON.stringify( $scope.get_location("http://localhost:257/index.php/deploy/?asd=asd#asd"),null,4 ) );