Подтвердить что ты не робот

Как проверить, является ли строка URL абсолютной или относительной?

Как проверить URL-адрес, если это относительный или абсолютный путь в Javascript или jQuery? Я хочу обрабатывать соответственно в зависимости, если переданный по URL-адресу является локальным или внешним путем.

if (urlString starts with http:// or https://)
 //do this
4b9b3361

Ответ 1

var pat = /^https?:\/\//i;
if (pat.test(urlString))
{
    //do stuff
}

Для относительных URL-адресов протокола используйте это регулярное выражение:

/^https?:\/\/|^\/\//i

Ответ 2

БЫСТРО

Если вам нужно проверить только http:// или https://, тогда наиболее эффективным способом будет:

if (urlString.indexOf('http://') === 0 || urlString.indexOf('https://') === 0)

UNIVERSAL

Однако я бы предложил более универсальный, не чувствительный к регистру, протокол-агностический подход:

var r = new RegExp('^(?:[a-z]+:)?//', 'i');
r.test('http://example.com'); // true - regular http absolute URL
r.test('HTTP://EXAMPLE.COM'); // true - HTTP upper-case absolute URL
r.test('https://www.exmaple.com'); // true - secure http absolute URL
r.test('ftp://example.com/file.txt'); // true - file transfer absolute URL
r.test('//cdn.example.com/lib.js'); // true - protocol-relative absolute URL
r.test('/myfolder/test.txt'); // false - relative URL
r.test('test'); // false - also relative URL

Объясните RegExp

^(?:[a-z]+:)?//

^ - начало строки
(?: - начало не захваченной группы
[a-z]+ - любой символ от 'a' до 'z' 1 или более раз
: - строка (символ двоеточия)
)? - конец незахваченной группы. Группа отображается 0 или 1 раз
// - строка (два символа косой черты)
'i' - флаг, нечувствительный к регистру

Ответ 3

Используйте регулярное выражение:

if (/^(?:[a-z]+:)?\/\//i.test(url))

Ответ 4

Оригинальный ответ

Очень быстрая и очень гибкая проверка:

if (url.indexOf('://') > 0 || url.indexOf('//') === 0 ) {
    // URL is absolute; either "http://example.com" or "//example.com"
} else {
    // URL is relative
}

Это распознает абсолютный URL, если:

  • URL содержит "://" в любом месте после первого символа или
  • URL начинается с "//" (относительный протокол)

  • Нет регулярных выражений.
  • Нет jQuery или другой зависимости.
  • Нет жестко заданных имен протоколов, которые делают условие чувствительным к регистру.
  • Никаких манипуляций со строками (например, toLowerCase или аналогичных).
  • Только проверки на "относительный или абсолютный", но не другие проверки работоспособности, могут использоваться для веб-адресов или любого внутреннего протокола.

Обновление 1 (пример полной функции)

Вот быстрая функция, которая возвращает истину/ложь для данного URL:

function isUrlAbsolute(url) { 
    return (url.indexOf('://') > 0 || url.indexOf('//') === 0);
}

И то же самое в ES6:

const isUrlAbsolute = (url) => (url.indexOf('://') > 0 || url.indexOf('//') === 0)

Обновление 2 (URL-адреса в параметре URL)

Для дополнительной адресации URL в формате /redirect?target=http://example.org я рекомендую использовать этот код:

function isUrlAbsolute(url) {
    if (url.indexOf('//') === 0) {return true;} // URL is protocol-relative (= absolute)
    if (url.indexOf('://') === -1) {return false;} // URL has no protocol (= relative)
    if (url.indexOf('.') === -1) {return false;} // URL does not contain a dot, i.e. no TLD (= relative, possibly REST)
    if (url.indexOf('/') === -1) {return false;} // URL does not contain a single slash (= relative)
    if (url.indexOf(':') > url.indexOf('/')) {return false;} // The first colon comes after the first slash (= relative)
    if (url.indexOf('://') < url.indexOf('.')) {return true;} // Protocol is defined before first dot (= absolute)
    return false; // Anything else must be relative
}

И то же в краткой форме и ES 6

// Traditional JS, shortened
function isUrlAbsolute(url) {
    return url.indexOf('//') === 0 ? true : url.indexOf('://') === -1 ? false : url.indexOf('.') === -1 ? false : url.indexOf('/') === -1 ? false : url.indexOf(':') > url.indexOf('/') ? false : url.indexOf('://') < url.indexOf('.') ? true : false;
}

// ES 6
const isUrlAbsolute = (url) => (url.indexOf('//') === 0 ? true : url.indexOf('://') === -1 ? false : url.indexOf('.') === -1 ? false : url.indexOf('/') === -1 ? false : url.indexOf(':') > url.indexOf('/') ? false : url.indexOf('://') < url.indexOf('.') ? true : false)

Вот несколько тестов:

// Test
console.log( isUrlAbsolute('http://stackoverflow.com') ) // -> true
console.log( isUrlAbsolute('//stackoverflow.com') ) // -> true
console.log( isUrlAbsolute('stackoverflow.com') ) // -> false
console.log( isUrlAbsolute('Ftp://example.net') ) // -> true
console.log( isUrlAbsolute('/redirect?target=http://example.org') ) // -> false

Обновление 3 (уточните относительные URL)

Я видел несколько комментариев о неправильном выводе:

  • Решение возвращает false для localhost
  • Сбой ответа на http:example.com

Однако эти URL-адреса действительно являются относительными URL-адресами. Это легко проверить:

  1. Создайте несколько папок на вашем локальном веб-корне, скажем, a/b/c/
  2. Создайте файл index.html и поместите в него следующую ссылку: <a href="localhost">test</a>
  3. Откройте страницу указателя в своем браузере: http://localhost/a/b/c/index.html и нажмите на ссылку. Вы закончите на http://localhost/a/b/c/localhost (а не на http://localhost)
  4. То же самое происходит при размещении ссылки http:example.com в вашем файле index.html. Вы заканчиваете на http://localhost/a/b/c/example.com вместо http://example.com

Ответ 5

В настоящее время, когда многие сервисы используют относительный URL-адрес протокола (например,//cdn.example.com/libary.js), этот метод безопаснее:

var isAbsolute = new RegExp('^([a-z]+://|//)', 'i');

if (isAbsolute.test(urlString)) {
  // go crazy here
}

Ответ 6

Еще более универсальный RFC-совместимый подход URI:

(?:^[az][a-z0-9+.-]*:|\/\/) объяснение регулярных выражений

Другие решения, перечисленные здесь, не mailto:[email protected] для таких ссылок, как mailto:[email protected]

RFC 3986 определяет схему как:

scheme = ALPHA *( ALPHA/DIGIT/"+"/"-"/"." )

3.1. Схема https://tools.ietf.org/html/rfc3986#section-3.1

Хотя относительный к протоколу URL-адрес технически действителен в соответствии с разделом 4.2, Пол Айриш повернул в другую сторону и считает это анти-паттерном. Смотрите http://www.paulirish.com/2010/the-protocol-relative-url/

4.2. Относительная ссылка http://tools.ietf.org/html/rfc3986#section-4.2

Если вы хотите использовать регулярное выражение без использования протокола:

^[az][a-z0-9+.-]*:

Чтобы увидеть полный список других типов действительных крайних случаев, ознакомьтесь со списком здесь: https://en.wikipedia.org/wiki/URI_scheme

Ответ 7

var external = RegExp('^(https?:)?//');
if(external.test(el)){
    // do something
}

EDIT:

При следующем регулярном выражении вы даже можете проверить, идет ли ссылка к одному домену или к внешнему:

var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');
if(external.test(el)){
    // do something
}

Ответ 8

Не используйте низкоуровневые вещи, такие как регулярные выражения и т.д. Эти вещи были решены многими другими людьми. Особенно крайние случаи.

Взгляните на URI.js, он должен выполнить свою работу: http://medialize.github.io/URI.js/docs.html#is

var uri = new URI("http://example.org/");
uri.is("absolute") === true;

Ответ 9

В зависимости от ваших потребностей, я думаю, что более надежный способ определить это - использовать встроенный интерфейс URL для создания пары объектов URL и сравнения источников.

new URL(document.baseURI).origin === new URL(urlToTest, document.baseURI).origin;

Это позволяет браузеру проанализировать и выяснить все это за вас, не беспокоясь о побочных эффектах крайних случаев.

Ответ 10

var adress = 'http://roflmao.com';
if (adress.substr(0,7) == 'http://' || adress.substr(0,8) == 'https://') {
    //
}

Ответ 11

Следующая функция вызывается, когда клик даже встречается на гиперссылке, т.е. тег 'a', если тег содержит url, будет относительным или содержит тот же хост, после чего новая страница будет загружена на ту же вкладку браузера, если она содержит другой URL-адрес, а затем страницу загрузится в новую вкладку браузера

jQuery(document).ready(function() {
    $('a').click(function(){

        var a = this;
        var a_href = $(this).attr('href');
        var regex = new RegExp('^(?:[a-z]+:)?//', 'i');     

        if(a.host == location.host || regex.test(a_href) == false){
            a.target = '_self';
        }else{
            a.target = '_blank';
        }
    }); 
});

Ответ 12

Вот пуленепробиваемый подход к проблеме:

Пусть браузер обрабатывает все для нас. Нет необходимости в некоторых сложных/подверженных ошибкам регулярных выражениях.

const isAbsoluteUrl = (url) => {
  const link = document.createElement('a');
  link.href = url;
  return link.origin + link.pathname + link.search + link.hash === url;
};

К сожалению, не работает в среде nodejs.

Ответ 13

var isExternalURL = url.toLowerCase().indexOf('http://') === 0 || url.toLowerCase().indexOf('https://') === 0 ;