Como extrair o URL base de uma string em JavaScript?

168

Estou tentando encontrar um método relativamente fácil e confiável para extrair o URL base de uma variável de string usando JavaScript (ou jQuery).

Por exemplo, considerando algo como:

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

Eu gostaria de obter:

http://www.sitename.com/

Uma expressão regular é a melhor aposta? Em caso afirmativo, qual declaração eu poderia usar para atribuir o URL base extraído de uma determinada string a uma nova variável?

Eu fiz algumas pesquisas sobre isso, mas tudo o que encontro no mundo do JavaScript parece girar em torno da coleta dessas informações a partir da URL real do documento usando location.host ou similar.

Estragar
fonte
Agora a resposta dos dias deve ser esta abaixo
davidmpaz

Respostas:

205

Edit: Alguns reclamam que não leva em conta o protocolo. Por isso, decidi atualizar o código, pois está marcado como resposta. Para quem gosta de código de linha única ... desculpe por isso que usamos minimizadores de código, o código deve ser legível por humanos e, dessa forma, é melhor ... na minha opinião.

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

Ou use a solução Davids abaixo.

itzhar
fonte
6
Obrigado pela resposta, mas novamente, estou tentando extrair o URL base de uma string, em vez do URL do documento real. Eu não acho que isso vai me ajudar - embora, por favor, me corrija se eu estiver errado.
Bungle
2
pathArray = String (" YourHost.com/url/nic/or/not").split ('/'); host = pathArray [2];
4
Entendi - graças Rafal e daddywoodland! Acabei usando: url = ' sitename.com/article/2009/09/14/this-is-an-article '; pathArray = (url) .split ('/'); host = 'http: //' + pathArray [2]; Acho que o exemplo de Rafal simplesmente omitiu o "http: //" que está presente em todas as strings que estou processando; nesse caso, o pathArray [2] é o que você precisa. Sem o prefixo "http: //", pathArray [0] seria o único. Obrigado novamente.
Bungle
4
Por que toda a declaração de variável? url = 'sitename.com/article/2009/09/14/this-is-an-article'; newurl = 'http://' + url.split('/')[0];
ErikE 21/08/10
1
pathArray = window.location.href.split ('/'); protocol = pathArray [0]; host = pathArray [2]; url = protocolo + ': //' + host; //now url === "http:://stackoverflow.com" checkout::
154

Os navegadores baseados no WebKit, o Firefox a partir da versão 21 e as versões atuais do Internet Explorer (IE 10 e 11) são implementadas location.origin.

location.origininclui o protocolo , o domínio e, opcionalmente, a porta da URL.

Por exemplo, location.origino URL http://www.sitename.com/article/2009/09/14/this-is-an-article/é http://www.sitename.com.

Para direcionar navegadores sem suporte para location.originusar o seguinte polyfill conciso:

if (typeof location.origin === 'undefined')
    location.origin = location.protocol + '//' + location.host;
David
fonte
36
window.location.hostnamesentirá falta do número da porta, se for o caso, então use window.location.host. Portanto, o 'nome da base' completo, incluindo a barra à direita, seria:window.location.protocol+"//"+window.location.host + "/";
sroebuck 30/08/11
4
Na verdade, window.location.hostname ainda é útil se, como no meu caso, você precisar fornecer um número de porta diferente.
Darrell Brogdon
44

Não precisa usar jQuery, apenas use

location.hostname
Daddywoodland
fonte
5
Obrigado - eu não posso usar isso com uma string, posso? Entendo que só funcionará com o URL do documento.
Bungle
2
Isso não inclui protocolo e porta.
David
32

Não há razão para fazer divisões para obter o caminho, o nome do host etc. a partir de uma sequência que é um link. Você só precisa usar um link

//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);

Você pode fazer isso facilmente com o jQuery anexando o elemento e lendo seu atributo.

epascarello
fonte
6
Por que adicionar 50K de jQuery quando você mostrou como fazê-lo sem o jQuery em alguns bytes?
Tim Down
13
Porque o pôster diz que eles estão usando jQuery.
epascarello
1
Ah sim, é justo. Embora, quando é tão simples assim, não vejo valor em usar a camada extra de abstração que o jQuery adicionaria.
Tim Down
2
Estamos assumindo que todo o site é executado no jqUERY, nesse caso, o kquery realmente simplificaria as coisas.
trusktr
2
Ewww ... essa não é a melhor maneira de fazer isso ... Se extrair de window.location.href, use window.location. Caso contrário, use uma regex.
BMiner
21
var host = location.protocol + '//' + location.host + '/';
kta
fonte
2
Isto deve ser considerado a resposta correta - que mantém o protocolo
Katai
16
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};

}

Então :

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

Para sua solicitação, você precisa de:

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

Revisão 07-2017: Também pode ser mais elegante e possui mais recursos

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

Então

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"

Legal!

Abdennour TOUMI
fonte
12

Se você estiver usando jQuery, essa é uma maneira interessante de manipular elementos em javascript sem adicioná-los ao 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
Wayne
fonte
1
Eu acho que deveria ser myAnchor.prop('hostname'). Acho que o jQuery mudou nos últimos 5 anos ... Obrigado pela resposta!
Dehli
11

Uma abordagem leve, mas completa, para obter valores básicos a partir de uma representação de string de um URL é a regra de regexp de Douglas Crockford:

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]+'/' ;

Se você está procurando um kit de ferramentas de manipulação de URL mais poderoso, experimente o URI.js Ele suporta getters, setter, normalização de URL, etc., todos com uma ótima API encadeada.

Se você está procurando um plugin jQuery, o jquery.url.js deve ajudá-lo

Uma maneira mais simples de fazer isso é usar um elemento âncora, como o @epascarello sugeriu. Isso tem a desvantagem de que você deve criar um elemento DOM. No entanto, isso pode ser armazenado em cache em um fechamento e reutilizado para vários URLs:

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

Use-o assim:

paserUrl('http://google.com');
alexandru.topliceanu
fonte
10

Bem, o objeto da API da URL evita dividir e construir manualmente os URLs .

 let url = new URL('/programming/1420881');
 alert(url.origin);
devansvd
fonte
8

Se você estiver extraindo informações de window.location.href (a barra de endereço), use este código para obter http://www.sitename.com/:

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

Se você tiver uma sequência, strou seja, um URL arbitrário (não window.location.href), use expressões regulares:

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

Eu, como todo mundo no Universo, odeio ler expressões regulares, então vou descrevê-lo em inglês:

  • Encontre zero ou mais caracteres alfa seguidos por dois pontos (o protocolo, que pode ser omitido)
  • Seguido por // (também pode ser omitido)
  • Seguido por qualquer caractere, exceto / (o nome do host e a porta)
  • Seguido por /
  • Seguido por qualquer que seja (o caminho, menos o começo /).

Não há necessidade de criar elementos DOM ou fazer qualquer coisa louca.

BMiner
fonte
7

Eu uso um regex simples que extrai o host do URL:

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

e use assim

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

Observe que, se urlnão terminar com /a host, não terminará em a /.

Aqui estão alguns testes:

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/');
    });
});
Michael_Scharf
fonte
6

Você pode usar os códigos abaixo para obter diferentes parâmetros do URL atual

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);
Nimesh07
fonte
4
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 + "/";
    }

}

Você pode usá-lo assim ...

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

O valor do URL será ...

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

O "var url" também contém dois métodos.

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

Nesse caso, o valor de paramQ será 1.

var allParameters = url.getParameters();

O valor de allParameters será apenas o nome dos parâmetros.

["q","t"]

Testado no IE, chrome e firefox.

shaikh
fonte
1
Acho que estou perdendo alguma coisa ... De onde vem o url?
thomasf1
3

Em vez de ter que considerar window.location.protocol e window.location.origin e possivelmente perder um número de porta especificado, etc., basta pegar tudo até o terceiro "/":

// 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);
}
sova
fonte
2

Isso funciona:

location.href.split(location.pathname)[0];
Alain Beauvois
fonte
1
falha no caso em quelocation.pathname = '/'
mido
1

Você pode fazer isso usando uma regex:

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

serve ?

Clement Herreman
fonte
1
Hmm, pelas minhas habilidades limitadas em regex, parece que isso é pelo menos próximo. Adicionarei mais algumas informações à pergunta para ver se posso ajudar a diminuir o melhor regex.
Bungle
1
Acabei usando .split ('/') na string apenas porque era uma solução mais fácil para mim. Obrigado pela sua ajuda!
Bungle
2
https URLs? Os nomes de host não começam com www? Por que capturar o www mesmo assim?
21139 Tim Down
1
Não sei, o OP perguntou como pegar um URL e, no exemplo dele, havia http & www.
Clement Herreman
1

Para obter a origem de qualquer URL, incluindo caminhos dentro de um site ( /my/path) ou sem esquema ( //example.com/my/path) ou completo ( http://example.com/my/path), montei uma função rápida.

No trecho abaixo, todas as três chamadas devem ser registradas 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'));

Tom Kay
fonte
0

Isso funciona para mim:

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] + '/';
    }
  }
};

abelabbesnabi
fonte
0
var tilllastbackslashregex = new RegExp(/^.*\//);
baseUrl = tilllastbackslashregex.exec(window.location.href);

window.location.href fornece o endereço de URL atual da barra de endereços do navegador

pode ser algo como https://stackoverflow.com/abc/xyz ou https://www.google.com/search?q=abc tilllastbackslashregex.exec () execute regex e execute novamente a sequência correspondente até a última barra invertida, ou seja, https : //stackoverflow.com/abc/ ou https://www.google.com/ respectivamente

Hasib Ullah Khan
fonte
5
Por favor, adicione uma breve descrição.
Preet
6
Da fila de revisão : Posso solicitar que você adicione algum contexto ao seu código-fonte. As respostas somente de código são difíceis de entender. Ajudará tanto os solicitantes quanto os futuros leitores, se você puder adicionar mais informações em sua postagem.
RBT
0

Uma boa maneira é usar o URLobjeto de API nativa do JavaScript . Isso fornece muitas partes úteis de URL.

Por exemplo:

const url = '/programming/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: "/programming/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

Como você pode ver aqui, basta acessar o que precisar.

Por exemplo: console.log(urlObject.host); // "stackoverflow.com"

doc para URL

V. Sambor
fonte