it-swarm.com.ru

Проверьте, является ли строка JavaScript URL

Есть ли в JavaScript способ проверить, является ли строка URL-адресом?

RegExes исключены, потому что URL, скорее всего, написан как stackoverflow; то есть он может не иметь .com, www или http.

153
Bruno

Смежный вопрос с ответом:

Соответствие URL регулярного выражения Javascript

Или это регулярное выражение из Devshed :

function validURL(str) {
  var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
    '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
    '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
    '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
    '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
    '(\\#[-a-z\\d_]*)?$','i'); // fragment locator
  return !!pattern.test(str);
}
68
Tom Gullen
function isURL(str) {
  var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
  '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|'+ // domain name
  '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
  '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
  '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
  '(\\#[-a-z\\d_]*)?$','i'); // fragment locator
  return pattern.test(str);
}
156
Zemljoradnik

Вместо того, чтобы использовать регулярное выражение, я бы рекомендовал использовать элемент привязки. 

когда вы устанавливаете свойство href для anchor, устанавливаются различные другие свойства. 

var parser = document.createElement('a');
parser.href = "http://example.com:3000/pathname/?search=test#hash";

parser.protocol; // => "http:"
parser.hostname; // => "example.com"
parser.port;     // => "3000"
parser.pathname; // => "/pathname/"
parser.search;   // => "?search=test"
parser.hash;     // => "#hash"
parser.Host;     // => "example.com:3000"

источник

Однако, если значение, к которому привязан href, не является допустимым URL-адресом, значением этих вспомогательных свойств будет пустая строка.

Edit:, как указано в комментариях: если используется неверный URL, свойства текущего URL могут быть заменены.

Итак, если вы не передаете URL текущей страницы, вы можете сделать что-то вроде:

function isValidURL(str) {
   var a  = document.createElement('a');
   a.href = str;
   return (a.Host && a.Host != window.location.Host);
}
74
Luke

Вы можете попробовать использовать URL конструктор : если он не выбрасывает, строка является допустимым URL:

const isValidUrl = (string) => {
  try {
    new URL(string);
    return true;
  } catch (_) {
    return false;  
  }
}
36
Pavlo

Чтобы проверить URL с помощью JavaScript, показано ниже

function ValidURL(str) {
  var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
  if(!regex .test(str)) {
    alert("Please enter valid URL.");
    return false;
  } else {
    return true;
  }
}
25
kavitha Reddy

Улучшение принятого ответа ...

  • Проверьте ftp/ftps как протокол
  • Имеет двойной выход для обратной косой черты (\\)
  • Гарантирует, что домены имеют точку и расширение (.com .io .xyz)
  • Позволяет использовать двоеточие (:) в пути, например http://thingiverse.com/download:1894343
  • Позволяет использовать амперсанд (&) в пути, например, http://en.wikipedia.org/wiki/Procter_&_Gamble
  • Позволяет символ @ в пути, например https://medium.com/@techytimo

    isURL(str) {
      var pattern = new RegExp('^((ft|htt)ps?:\\/\\/)?'+ // protocol
      '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name and extension
      '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
      '(\\:\\d+)?'+ // port
      '(\\/[-a-z\\d%@_.~+&:]*)*'+ // path
      '(\\?[;&a-z\\d%@_.,~+&:=-]*)?'+ // query string
      '(\\#[-a-z\\d_]*)?$','i'); // fragment locator
      return pattern.test(str);
    }
    
20
TechyTimo

Положитесь на библиотеку: https://www.npmjs.com/package/valid-url

import { isWebUri } from 'valid-url';
// ...
if (!isWebUri(url)) {
    return "Not a valid url.";
}
19
Michael Bushe

Я использую функцию ниже для проверки URL с или без http/https:

function isValidURL(string) {
  var res = string.match(/(http(s)?:\/\/.)?(www\.)?[[email protected]:%._\+~#=]{2,256}\.[a-z]{2,6}\b([[email protected]:%_\+.~#?&//=]*)/g);
  if (res == null)
    return false;
  else
    return true;
};

var testCase1 = "http://en.wikipedia.org/wiki/Procter_&_Gamble";
console.log(isValidURL(testCase1)); // return true

var testCase2 = "http://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&docid=nIv5rk2GyP3hXM&tbnid=isiOkMe3nCtexM:&ved=0CAUQjRw&url=http%3A%2F%2Fanimalcrossing.wikia.com%2Fwiki%2FLion&ei=ygZXU_2fGKbMsQTf4YLgAQ&bvm=bv.65177938,d.aWc&psig=AFQjCNEpBfKnal9kU7Zu4n7RnEt2nerN4g&ust=1398298682009707";
console.log(isValidURL(testCase2)); // return true

var testCase3 = "https://sdfasd";
console.log(isValidURL(testCase3)); // return false

var testCase4 = "dfdsfdsfdfdsfsdfs";
console.log(isValidURL(testCase4)); // return false

var testCase5 = "magnet:?xt=urn:btih:123";
console.log(isValidURL(testCase5)); // return false

var testCase6 = "https://stackoverflow.com/";
console.log(isValidURL(testCase6)); // return true

var testCase7 = "https://w";
console.log(isValidURL(testCase7)); // return false

var testCase8 = "https://sdfasdp.ppppppppppp";
console.log(isValidURL(testCase8)); // return false

16
VicJordan

Вот еще один метод.

var Elm;
function isValidURL(u){
  if(!Elm){
    Elm = document.createElement('input');
    Elm.setAttribute('type', 'url');
  }
  Elm.value = u;
  return Elm.validity.valid;
}

console.log(isValidURL('http://www.google.com/'));
console.log(isValidURL('//google.com'));
console.log(isValidURL('google.com'));
console.log(isValidURL('localhost:8000'));

10
Ryan

(У меня нет представителей, чтобы комментировать ValidURL пример; поэтому опубликуйте это как ответ.)

Хотя использование относительных к протоколу URL не рекомендуется ( относительные к протоколу URL ), они иногда работают. Для проверки правильности такого URL-адреса с помощью регулярного выражения часть протокола может быть необязательной, например:

function isValidURL(str) {
    var pattern = new RegExp('^((https?:)?\\/\\/)?'+ // protocol
        '(?:\\S+(?::\\S*)[email protected])?' + // authentication
        '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
        '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
        '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
        '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
        '(\\#[-a-z\\d_]*)?$','i'); // fragment locater
    if (!pattern.test(str)) {
        return false;
    } else {
        return true;
    }
}

Однако, как отмечали другие, регулярное выражение, похоже, не является наиболее подходящим подходом для проверки URL-адресов. 

8
ko la

Я не могу комментировать пост, который является самым близким # 5717133 , но ниже показано, как я понял, как заставить работать @ tom-gullen regex.

/^(https?:\/\/)?((([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|((\d{1,3}\.){3}\d{1,3}))(\:\d+)?(\/[-a-z\d%_.~+]*)*(\?[;&a-z\d%_.~+=-]*)?(\#[-a-z\d_]*)?$/i
5
iamnewton

Как уже отмечалось, идеальное регулярное выражение неуловимо, но все же кажется разумным подходом (альтернативы - тесты на стороне сервера или новый экспериментальный URL API ). Однако высокопоставленные ответы часто возвращают false для обычных URL-адресов, но, что еще хуже, ваше приложение/страница будет зависать на несколько минут даже на такой простой строке, как isURL('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'). На это было указано в некоторых комментариях, но, скорее всего, для его просмотра не было введено неправильное значение. Такое зависание делает этот код непригодным для использования в любом серьезном приложении. Я думаю, что это связано с повторяющимися нечувствительными к регистру наборами в коде типа ((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' .... Уберите «я», и оно не будет зависать, но, конечно, не будет работать так, как хотелось бы. Но даже с флагом игнорирования регистра эти тесты отклоняют допустимые высокие значения Юникода.

Лучшее уже упоминалось:

function isURL(str) {
  return /^(?:\w+:)?\/\/([^\s\.]+\.\S{2}|localhost[\:?\d]*)\S*$/.test(str); 
}

Это происходит от Github segmentio/is-url . Хорошая вещь о репозитории кода - вы можете видеть тестирование и любые проблемы, а также тестовые строки, проходящие через него. Есть ветка, которая позволяла бы протоколам пропустить строки, такие как google.com, хотя вы, вероятно, делаете слишком много предположений. Репозиторий был обновлен, и я не планирую пытаться сохранить здесь зеркало. Он разбит на отдельные тесты, чтобы избежать RegEx redos , которые могут быть использованы для атак DOS (я не Я думаю, вам нужно беспокоиться об этом с js на стороне клиента, но вам нужно беспокоиться о том, что ваша страница зависает так долго, что ваш посетитель покидает ваш сайт).

Есть еще один репозиторий, который я видел, что может быть даже лучше для isURL в dperini/regex-weburl.js, но он очень сложный. Он имеет больший тестовый список действительных и недействительных URL. Простой, приведенный выше, по-прежнему пропускает все позитивы и не может блокировать только несколько нечетных негативов, таких как http://a.b--c.de/, а также специальные ips.

Независимо от того, что вы выберете, запустите его с помощью этой функции, которую я адаптировал из тестов dperini/regex-weburl.js, в то же время используя инспектор инструментов разработчика вашего браузера.

function testIsURL() {
//should match
console.assert(isURL("http://foo.com/blah_blah"));
console.assert(isURL("http://foo.com/blah_blah/"));
console.assert(isURL("http://foo.com/blah_blah_(wikipedia)"));
console.assert(isURL("http://foo.com/blah_blah_(wikipedia)_(again)"));
console.assert(isURL("http://www.example.com/wpstyle/?p=364"));
console.assert(isURL("https://www.example.com/foo/?bar=baz&inga=42&quux"));
console.assert(isURL("http://✪df.ws/123"));
console.assert(isURL("http://userid:[email protected]:8080"));
console.assert(isURL("http://userid:[email protected]:8080/"));
console.assert(isURL("http://[email protected]"));
console.assert(isURL("http://[email protected]/"));
console.assert(isURL("http://[email protected]:8080"));
console.assert(isURL("http://[email protected]:8080/"));
console.assert(isURL("http://userid:[email protected]"));
console.assert(isURL("http://userid:[email protected]/"));
console.assert(isURL("http://142.42.1.1/"));
console.assert(isURL("http://142.42.1.1:8080/"));
console.assert(isURL("http://➡.ws/䨹"));
console.assert(isURL("http://⌘.ws"));
console.assert(isURL("http://⌘.ws/"));
console.assert(isURL("http://foo.com/blah_(wikipedia)#cite-1"));
console.assert(isURL("http://foo.com/blah_(wikipedia)_blah#cite-1"));
console.assert(isURL("http://foo.com/unicode_(✪)_in_parens"));
console.assert(isURL("http://foo.com/(something)?after=parens"));
console.assert(isURL("http://☺.damowmow.com/"));
console.assert(isURL("http://code.google.com/events/#&product=browser"));
console.assert(isURL("http://j.mp"));
console.assert(isURL("ftp://foo.bar/baz"));
console.assert(isURL("http://foo.bar/?q=Test%20URL-encoded%20stuff"));
console.assert(isURL("http://مثال.إختبار"));
console.assert(isURL("http://例子.测试"));
console.assert(isURL("http://उदाहरण.परीक्षा"));
console.assert(isURL("http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com"));
console.assert(isURL("http://1337.net"));
console.assert(isURL("http://a.b-c.de"));
console.assert(isURL("http://223.255.255.254"));
console.assert(isURL("postgres://u:[email protected]:5702/db"));
console.assert(isURL("https://[email protected]/13176"));

//SHOULD NOT MATCH:
console.assert(!isURL("http://"));
console.assert(!isURL("http://."));
console.assert(!isURL("http://.."));
console.assert(!isURL("http://../"));
console.assert(!isURL("http://?"));
console.assert(!isURL("http://??"));
console.assert(!isURL("http://??/"));
console.assert(!isURL("http://#"));
console.assert(!isURL("http://##"));
console.assert(!isURL("http://##/"));
console.assert(!isURL("http://foo.bar?q=Spaces should be encoded"));
console.assert(!isURL("//"));
console.assert(!isURL("//a"));
console.assert(!isURL("///a"));
console.assert(!isURL("///"));
console.assert(!isURL("http:///a"));
console.assert(!isURL("foo.com"));
console.assert(!isURL("rdar://1234"));
console.assert(!isURL("h://test"));
console.assert(!isURL("http:// shouldfail.com"));
console.assert(!isURL(":// should fail"));
console.assert(!isURL("http://foo.bar/foo(bar)baz quux"));
console.assert(!isURL("ftps://foo.bar/"));
console.assert(!isURL("http://-error-.invalid/"));
console.assert(!isURL("http://a.b--c.de/"));
console.assert(!isURL("http://-a.b.co"));
console.assert(!isURL("http://a.b-.co"));
console.assert(!isURL("http://0.0.0.0"));
console.assert(!isURL("http://10.1.1.0"));
console.assert(!isURL("http://10.1.1.255"));
console.assert(!isURL("http://224.1.1.1"));
console.assert(!isURL("http://1.1.1.1.1"));
console.assert(!isURL("http://123.123.123"));
console.assert(!isURL("http://3628126748"));
console.assert(!isURL("http://.www.foo.bar/"));
console.assert(!isURL("http://www.foo.bar./"));
console.assert(!isURL("http://.www.foo.bar./"));
console.assert(!isURL("http://10.1.1.1"));}

А затем проверить эту строку «а».

Смотрите это сравнение isURL regex от Mathias Bynens для получения дополнительной информации, прежде чем публиковать, казалось бы, замечательное регулярное выражение.

5
aamarks

Одна функция, которую я использовал для проверки URL-адреса «строка»:

var matcher = /^(?:\w+:)?\/\/([^\s\.]+\.\S{2}|localhost[\:?\d]*)\S*$/;

function isUrl(string){
  return matcher.test(string);
}

Эта функция возвращает логическое значение, является ли строка URL-адресом.

Примеры:

isUrl("https://google.com");     // true
isUrl("http://google.com");      // true
isUrl("http://google.de");       // true
isUrl("//google.de");            // true
isUrl("google.de");              // false
isUrl("http://google.com");      // true
isUrl("http://localhost");       // true
isUrl("https://sdfasd");         // false
4
Chris

это работает со мной

function isURL(str) {
  var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
  var pattern = new RegExp(regex); 
return pattern.test(str);
}
2
HeshamSalama

Вопрос задает метод проверки для URL, такого как stackoverflow, без протокола или любой точки в имени хоста. Таким образом, дело не в проверке синтаксиса URL, а в проверке, является ли он действительным, путем его фактического вызова.

Я попробовал несколько способов узнать, существует ли URL-адрес true и может ли он вызываться из браузера, но не нашел способа проверить с помощью javascript заголовок ответа на вызов:

  • добавление элемента привязки прекрасно для запуска метода click()
  • выполнение ajax-вызова на вызывающий URL с помощью 'GET' - это хорошо, но оно имеет различные ограничения из-за политик CORS, и это не относится к использованию ajax, поскольку в качестве URL-адреса может использоваться любой другой домен за пределами домена моего сервера.
  • использование fetch API имеет обходной путь, похожий на ajax.
  • другая проблема заключается в том, что мой сервер работает по протоколу https и выдает исключение при вызове незащищенных URL-адресов.

Итак, лучшее решение, которое я могу придумать, - это получить какой-нибудь инструмент для выполнения CURL с использованием javascript, пытаясь что-то вроде curl -I <url>. К сожалению, я не нашел ни одного, и на первый взгляд это не возможно. Буду признателен за любые комментарии по этому вопросу.

Но, в конце концов, у меня есть сервер, на котором работает PHP, и, поскольку я использую Ajax почти для всех своих запросов, я написал функцию на стороне сервера, чтобы выполнить там запрос curl и вернуться в браузер. 

Что касается отдельного URL-адреса Word по вопросу «stackoverflow», это приведет меня к https://daniserver.com.ar/stackoverflow, где daniserver.com.ar - мой собственный домен. 

1
Daniel Faure

Вы можете использовать URL native API :

  const isUrl = string => {
      try { return Boolean(new URL(string)); }
      catch(e){ return false; }
  }
1
Aral Roca

Это довольно сложно сделать с помощью регулярных выражений, потому что URL-адреса имеют много «неудобств».

  1. Например, доменные имена имеют сложные ограничения на дефисы:

    а. Разрешено иметь много последовательных дефисов в середине.

    б. но первый и последний символ доменного имени не может быть дефисом

    с. 3-й и 4-й символ не может быть дефисом 

  2. Аналогично, номер порта может быть только в диапазоне 1-65535. Это легко проверить, если вы извлекаете часть порта и конвертируете в int, но это довольно сложно проверить с помощью регулярного выражения.

  3. Также нет простого способа проверить действительные доменные расширения. В некоторых странах есть домены второго уровня (например, «co.uk»), или расширение может быть длинным словом, например «.international». И новые TLD добавляются регулярно. Этот тип вещей может быть проверен только по жестко закодированному списку. (см. https://en.wikipedia.org/wiki/Top-level_domain )

  4. Тогда есть URL-адреса магнитов, адреса FTP и т.д. Все они имеют различные требования.

Тем не менее, вот функция, которая обрабатывает почти все, кроме:

  • Случай 1. с
  • Принимает любой 1-5-значный номер порта
  • Принимает любое продление 2-13 символов
  • Не принимает фтп, магнит и т.д ...

function isValidURL(input) {
    pattern = '^(https?:\\/\\/)?' + // protocol
        '((([a-zA-Z\\d]([a-zA-Z\\d-]{0,61}[a-zA-Z\\d])*\\.)+' + // sub-domain + domain name
        '[a-zA-Z]{2,13})' + // extension
        '|((\\d{1,3}\\.){3}\\d{1,3})' + // OR ip (v4) address
        '|localhost)' + // OR localhost
        '(\\:\\d{1,5})?' + // port
        '(\\/[a-zA-Z\\&\\d%_.~+-:@]*)*' + // path
        '(\\?[a-zA-Z\\&\\d%_.,~+-:@=;&]*)?' + // query string
        '(\\#[-a-zA-Z&\\d_]*)?$'; // fragment locator
    regex = new RegExp(pattern);
    return regex.test(input);
}

let tests = [];
tests.Push(['', false]);
tests.Push(['http://en.wikipedia.org/wiki/Procter_&_Gamble', true]);
tests.Push(['https://sdfasd', false]);
tests.Push(['http://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&docid=nIv5rk2GyP3hXM&tbnid=isiOkMe3nCtexM:&ved=0CAUQjRw&url=http%3A%2F%2Fanimalcrossing.wikia.com%2Fwiki%2FLion&ei=ygZXU_2fGKbMsQTf4YLgAQ&bvm=bv.65177938,d.aWc&psig=AFQjCNEpBfKnal9kU7Zu4n7RnEt2nerN4g&ust=1398298682009707', true]);
tests.Push(['https://stackoverflow.com/', true]);
tests.Push(['https://w', false]);
tests.Push(['aaa', false]);
tests.Push(['aaaa', false]);
tests.Push(['oh.my', true]);
tests.Push(['dfdsfdsfdfdsfsdfs', false]);
tests.Push(['google.co.uk', true]);
tests.Push(['test-domain.MUSEUM', true]);
tests.Push(['-hyphen-start.gov.tr', false]);
tests.Push(['hyphen-end-.com', false]);
tests.Push(['https://sdfasdp.international', true]);
tests.Push(['https://sdfasdp.pppppppp', false]);
tests.Push(['https://sdfasdp.ppppppppppppppppppp', false]);
tests.Push(['https://sdfasd', false]);
tests.Push(['https://sub1.1234.sub3.sub4.sub5.co.uk/?', true]);
tests.Push(['http://www.google-com.123', false]);
tests.Push(['http://my--testdomain.com', false]);
tests.Push(['http://my2nd--testdomain.com', true]);
tests.Push(['http://thingiverse.com/download:1894343', true]);
tests.Push(['https://medium.com/@techytimo', true]);
tests.Push(['http://localhost', true]);
tests.Push(['localhost', true]);
tests.Push(['localhost:8080', true]);
tests.Push(['localhost:65536', true]);
tests.Push(['localhost:80000', false]);
tests.Push(['magnet:?xt=urn:btih:123', true]);

for (let i = 0; i < tests.length; i++) {
    console.log('Test #' + i + (isValidURL(tests[i][0]) == tests[i][1] ? ' passed' : ' failed') + ' on ["' + tests[i][0] + '", ' + tests[i][1] + ']');
}

1
Caner

В моем случае мое единственное требование состоит в том, чтобы пользовательский ввод не интерпретировался как относительная ссылка, если он помещен в href тега, и ответы здесь были либо немного OTT для этого, либо разрешенные URL не соответствуют моим требованиям, поэтому это это то, что я собираюсь с:

^https?://.+$

То же самое может быть достигнуто довольно легко без регулярных выражений.

0
rdans

Кажется, это одна из самых сложных проблем в CS;)

Вот еще одно неполное решение, которое работает достаточно хорошо для меня и лучше, чем другие, которые я видел здесь. Я использую input [type = url] для этого, чтобы поддержать IE11, иначе было бы намного проще использовать window.URL вместо проверки:

const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
function isValidIpv4(ip) {
  if (!ipv4Regex.test(ip)) return false;
  return !ip.split('.').find(n => n > 255);
}

const domainRegex = /(?:[a-z0-9-]{1,63}\.){1,125}[a-z]{2,63}$/i;
function isValidDomain(domain) {
  return isValidIpv4(domain) || domainRegex.test(domain);
}

let input;
function validateUrl(url) {
  if (! /^https?:\/\//.test(url)) url = `http://${url}`; // assuming Babel is used
  // to support IE11 we'll resort to input[type=url] instead of window.URL:
  // try { return isValidDomain(new URL(url).Host) && url; } catch(e) { return false; }
  if (!input) { input = document.createElement('input'); input.type = 'url'; }
  input.value = url;
  if (! input.validity.valid) return false;
  const domain = url.split(/^https?:\/\//)[1].split('/')[0].split('@').pop();
  return isValidDomain(domain) && url;
}

console.log(validateUrl('google'), // false
  validateUrl('user:[email protected]'),
  validateUrl('https://google.com'),
  validateUrl('100.100.100.100/abc'),
  validateUrl('100.100.100.256/abc')); // false

Чтобы принять неполные данные, такие как «www.mydomain.com», он также сделает его действительным, если в этих случаях протокол будет «http», и вернет действительный URL, если адрес действителен. Возвращает ложь, когда недействителен.

Он также поддерживает домены IPv4, но не IPv6.

0
rosenfeld

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

is_valid_url = ( $url ) => {

    let $url_object = null;

    try {
        $url_object = new URL( $url );
    } catch ( $error ) {
        return false;
    }

    const $protocol = $url_object.protocol;
    const $protocol_position = $url.lastIndexOf( $protocol );
    const $domain_extension_position = $url.lastIndexOf( '.' );

    return (
        $protocol_position === 0 &&
        [ 'http:', 'https:' ].indexOf( $protocol ) !== - 1 &&
        $domain_extension_position > 2 && $url.length - $domain_extension_position > 2
    );

};
0
Michael Ecklund

Я думаю, что использование нативного URL API лучше сложных шаблонов регулярных выражений, как предложил @pavlo. У него есть некоторые недостатки, которые мы можем исправить с помощью дополнительного кода. Этот подход не подходит для следующего действительного URL.

//cdn.google.com/script.js

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

http://w
http://..

Так зачем проверять весь URL? мы можем просто проверить домен. Я позаимствовал регулярное выражение для проверки домена из здесь

function isValidUrl(string) {
    if (string && string.length > 1 && string.slice(0, 2) == '//') {
        string = 'http:' + string; //dummy protocol so that URL works
    }
    try {
        var url = new URL(string);
        return url.hostname && url.hostname.match(/^([a-z0-9])(([a-z0-9-]{1,61})?[a-z0-9]{1})?(\.[a-z0-9](([a-z0-9-]{1,61})?[a-z0-9]{1})?)?(\.[a-zA-Z]{2,4})+$/) ? true : false;
    } catch (_) {
        return false;
    }
}

Атрибут hostname является пустой строкой для javascript:void(0), поэтому он работает и для этого, и вы также можете добавить верификатор IP-адреса. Я бы хотел больше всего придерживаться нативного API и надеюсь, что он начнет поддерживать все в ближайшем будущем. 

0
Munim Munna