Как проверить, является ли строка URL абсолютной или относительной?
Как я могу проверить URL, если это относительный или абсолютный путь в Javascript или jQuery? Я хочу обрабатывать соответственно в зависимости от того, является ли переданный URL-адрес локальным или внешним путем.
if (urlString starts with http:// or https://)
//do this
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 (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:evan@nylas.com
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'; } }); });