Проверьте, является ли строка JavaScript URL - PullRequest
194 голосов
/ 19 апреля 2011

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

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

Ответы [ 22 ]

0 голосов
/ 26 июля 2018

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

Вот еще одно неполное решение, которое работает для меня достаточно хорошо и лучше, чем другие, которые я видел здесь. Я использую вход [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:pw@mydomain.com'),
  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 голосов
/ 17 апреля 2018

Я думаю, что использование нативного 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 и надеюсь, что он начнет поддерживать все в ближайшем будущем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...