Как извлечь базовый URL из строки в JavaScript?

168

Я пытаюсь найти относительно простой и надежный метод для извлечения базового URL из строковой переменной с помощью JavaScript (или jQuery).

Например, учитывая что-то вроде:

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

Я хотел бы получить:

http://www.sitename.com/

Является ли регулярное выражение лучшим выбором? Если да, то какой оператор я могу использовать, чтобы назначить базовый URL, извлеченный из заданной строки, новой переменной?

Я провел некоторый поиск по этому вопросу, но все, что я нахожу в мире JavaScript, похоже, вращается вокруг сбора этой информации из фактического URL документа, используя location.host или подобное.

неумело
источник
Ответ на этот
davidmpaz

Ответы:

205

Изменить: Некоторые жалуются, что он не учитывает протокол. Поэтому я решил обновить код, так как он помечен как ответ. Для тех, кто любит однострочный код ... ну, извините, поэтому мы используем минимизаторы кода, код должен быть удобочитаемым, и этот способ лучше ... на мой взгляд.

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

Или используйте решение Дэвидса снизу.

itzhar
источник
6
Спасибо за ответ, но опять же, я пытаюсь извлечь базовый URL из строки, а не фактический URL документа. Я не думаю, что это поможет мне - хотя, пожалуйста, поправьте меня, если я ошибаюсь.
Bungle
2
pathArray = String (" YourHost.com/url/nic/or/not").split ('/'); host = pathArray [2];
4
Понятно - спасибо Рафал и Daddywoodland! В итоге я использовал: url = ' sitename.com/article/2009/09/14/this-is-an-article '; pathArray = (url) .split ('/'); host = 'http: //' + pathArray [2]; Я думаю, что в примере с Rafal просто пропущено «http: //», присутствующее во всех строках, которые я обрабатываю, и в этом случае вам нужен pathArray [2]. Без префикса "http: //" будет использоваться pathArray [0]. Еще раз спасибо.
Bungle
4
Почему все объявления переменных? url = 'sitename.com/article/2009/09/14/this-is-an-article'; newurl = 'http://' + url.split('/')[0];
ErikE
1
pathArray = window.location.href.split ('/'); protocol = pathArray [0]; host = pathArray [2]; url = protocol + ': //' + host; //now url === "http:://stackoverflow.com"::
154

Реализованы браузеры на основе WebKit, Firefox начиная с версии 21 и текущие версии Internet Explorer (IE 10 и 11) location.origin.

location.originвключает в себя протокол , домен и опционально порт URL.

Например, location.originиз URL http://www.sitename.com/article/2009/09/14/this-is-an-article/есть http://www.sitename.com.

Для таргетинга браузеров без поддержки location.originиспользуйте следующий лаконичный полифилл:

if (typeof location.origin === 'undefined')
    location.origin = location.protocol + '//' + location.host;
Дэвид
источник
36
window.location.hostnameпропустит номер порта, если он указан, так что используйте window.location.host. Таким образом, полное «базовое имя», включая косую черту, будет:window.location.protocol+"//"+window.location.host + "/";
sroebuck
4
На самом деле, window.location.hostname все еще полезно, если, как и в моем случае, вам нужно указать другой номер порта.
Даррелл Брогдон
44

Не нужно использовать JQuery, просто используйте

location.hostname
daddywoodland
источник
5
Спасибо - я не могу использовать это со строкой, не так ли? Насколько я понимаю, это будет работать только с URL документа.
Bungle
2
Это не будет включать протокол и порт.
Дэвид
32

Нет причин делать расщепления, чтобы получить путь, имя хоста и т. Д. Из строки, которая является ссылкой. Вам просто нужно использовать ссылку

//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, добавляющего элемент и читающего его атрибут.

epascarello
источник
6
Зачем добавлять 50 КБ jQuery, если вы показали, как это сделать без jQuery, за несколько байтов?
Тим Даун
13
Потому что на плакате написано, что они используют jQuery.
epascarello
1
Ах да, достаточно справедливо. Хотя, когда это так просто, я не вижу смысла в использовании дополнительного уровня абстракции, который добавит использование jQuery.
Тим Даун
2
Мы предполагаем, что весь сайт работает на jqUERY в этом случае, kquery действительно упростит вещи.
trusktr
2
Ewww ... это не лучший способ сделать это ... Если вы извлекаете из window.location.href, используйте window.location. В противном случае используйте регулярное выражение.
BMiner
21
var host = location.protocol + '//' + location.host + '/';
КТА
источник
2
Это следует считать правильным ответом - он сохраняет протокол
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};

}

Затем :

'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"

Прохладно!

Абденнур ТУМИ
источник
12

Если вы используете 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
Wayne
источник
1
Я думаю, что так и должно быть myAnchor.prop('hostname'). Я предполагаю, что jQuery изменился за последние 5 лет ... Спасибо за ответ!
Дели
11

Легким, но полным подходом к получению базовых значений из строкового представления 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. Он поддерживает геттеры, сеттеры, нормализацию 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');
alexandru.topliceanu
источник
8

Если вы извлекаете информацию из 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 или делать что-то сумасшедшее.

BMiner
источник
7

Я использую простое регулярное выражение, которое извлекает хост из 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/');
    });
});
Michael_Scharf
источник
6

Вы можете использовать приведенные ниже коды для получения различных параметров текущего 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);
Nimesh07
источник
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 + "/";
    }

}

Затем вы можете использовать это так ...

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.

шайх
источник
1
Я думаю, что я что-то упустил ... Откуда приходит Урл?
thomasf1
3

Вместо необходимости учитывать window.location.protocol и window.location.origin и, возможно, пропустить указанный номер порта и т. Д., Просто захватите все до 3-го «/»:

// 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);
}
Шова
источник
2

Это работает:

location.href.split(location.pathname)[0];
Ален Бовуа
источник
1
терпит неудачу в случае, когдаlocation.pathname = '/'
мидо
1

Вы можете сделать это с помощью регулярного выражения:

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

это подходит ?

Клемент Эрреман
источник
1
Хм, из-за моих ограниченных навыков регулярных выражений, похоже, что это, по крайней мере, близко. Я добавлю еще немного информации к вопросу, чтобы посмотреть, смогу ли я помочь найти лучшее регулярное выражение.
Bungle
1
В итоге я использовал .split ('/') в строке только потому, что это было для меня более простым решением. Спасибо за вашу помощь, хотя!
Bungle
2
https URL? Имена хостов не начинаются с www? Зачем захватывать www в любом случае?
Тим Даун
1
Я не знаю, ОП спросил, как поймать URL, и в его примере были http & www.
Клемент Херреман
1

Чтобы получить источник любого URL, включая пути внутри веб-сайта ( /my/path) или schemaless ( //example.com/my/path), или full ( http://example.com/my/path), я собрал быструю функцию.

В приведенном ниже фрагменте все три вызова должны регистрироваться 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'));

Том Кей
источник
0

Это работает для меня:

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
источник
0
var tilllastbackslashregex = new RegExp(/^.*\//);
baseUrl = tilllastbackslashregex.exec(window.location.href);

window.location.href выдает текущий адрес URL из адресной строки браузера.

это может быть любая вещь, например https://stackoverflow.com/abc/xyz или https://www.google.com/search?q=abc tilllastbackslashregex.exec (), запустить regex и повторно выполнить сопоставленную строку до последней обратной косой черты, т.е. https : //stackoverflow.com/abc/ или https://www.google.com/ соответственно

Хасиб Улла Хан
источник
5
Пожалуйста, добавьте краткое описание.
Прит
6
Из очереди обзора : Могу ли я попросить вас добавить контекст вокруг вашего исходного кода. Ответы только на код трудно понять. Это поможет вам и будущим читателям, если вы сможете добавить больше информации в свой пост.
RBT
0

Хорошим способом является использование нативного URLобъекта API JavaScript . Это обеспечивает много полезных частей URL.

Например:

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

Как вы видите здесь, вы можете просто получить доступ ко всему, что вам нужно.

Например: console.log(urlObject.host); // "stackoverflow.com"

документ для URL

В. Самбор
источник