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


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

if (urlString starts with http:// or https://)
 //do this
11   52  

11 ответов:

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

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

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

быстро

Если вам нужно только проверить http:// или https:// тут наиболее эффективным!--16--> путь:

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

универсальная

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

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

объясните регулярное выражение

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

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

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

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

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

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

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

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

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

обновление

вот функция, которая возвращает true/false для данного URL-адреса:

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

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

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

обновление 2

для дополнительного адреса 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

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

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

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

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

(?:^[a-z][a-z0-9+.-]*:|\/\/)регулярное объяснение

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

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

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

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

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

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

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
}

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

посмотреть URI.js, он должен сделать работу:http://medialize.github.io/URI.js/docs.html#is

var uri = new URI("http://example.org/");
uri.is("absolute") === true;
var adress = 'http://roflmao.com';
if (adress.substr(0,7) == 'http://' || adress.substr(0,8) == 'https://') {
    //
}

следующая функция будет вызвана, когда щелчок даже происходит по гиперссылке, т. е. тег " 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';
        }
    }); 
});
var isExternalURL = url.toLowerCase().indexOf('http://') === 0 || url.toLowerCase().indexOf('https://') === 0 ;