Як перевірити, чи є рядок дійсною URL-адресою HTTP?


251

Існують Uri.IsWellFormedUriStringі Uri.TryCreateметоди, але вони, схоже, повертаються trueдо файлових шляхів тощо.

Як перевірити, чи рядок є дійсною (не обов'язково активною) HTTP-адресою для цілей перевірки введення?


Не використовуйте regex.IsMatch взагалі для перевірки URL-адреси. Може вбити процесор. stackoverflow.com/questions/31227785 / ...
inesmar

Відповіді:


451

Спробуйте це перевірити HTTP-адреси ( uriNameце URI, який ви хочете перевірити):

Uri uriResult;
bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) 
    && uriResult.Scheme == Uri.UriSchemeHttp;

Або, якщо ви хочете прийняти і HTTP, і HTTPS URL як дійсні (за коментарем J0e3gan):

Uri uriResult;
bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) 
    && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);

6
Чи повинен це читати uriResult.Scheme замість uriName.Scheme? Я використовую перевантаження для TryCreate, який приймає String замість Uri в якості першого параметра.

7
Ви можете додати більше умов до uriResult.Scheme == ... Конкретно https. Це залежить від того, для чого вам це потрібно, але ця невелика зміна була все, що мені потрібно, щоб вона працювала ідеально для мене.
Fiarr

11
Щоб бути зрозумілим за коментарем @ Fiarr, "невелика зміна", необхідна для обліку HTTPS на додаток до HTTP-адрес:bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps;
J0e3gan

3
таким чином не вдається отримати URL-адресу, як abcde . У ньому сказано, що це дійсна URL-адреса.
Kailash P

7
Схоже, ця методика не відповідає 22 з 75 тестів dotnetfiddle.net/XduN3A
whitneyland

98

Цей метод добре працює як у http, так і в https. Всього один рядок :)

if (Uri.IsWellFormedUriString("https://www.google.com", UriKind.Absolute))

MSDN: IsWellFormedUriString


13
Це повернеться істинним для URI, що не є HTTP (тобто будь-яка інша схема, наприклад, file://або ldap://. Це рішення має бути поєднане з перевіркою на схему, наприкладif (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) ...
Squiggle

Чи сумісний цей RFC3986?
Маркус

3
@Squiggle Це саме те, що я хочу перевірити, все, оскільки я роблю Downloader. Отже, ця відповідь є для мене найкращим методом.
Beyondo

24
    public static bool CheckURLValid(this string source)
    {
        Uri uriResult;
        return Uri.TryCreate(source, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp;
    }

Використання:

string url = "htts://adasd.xc.";
if(url.CheckUrlValid())
{
  //valid process
}

ОНОВЛЕННЯ: (один рядок коду) Спасибі @GoClimbColorado

public static bool CheckURLValid(this string source) => Uri.TryCreate(source, UriKind.Absolute, out Uri uriResult) && uriResult.Scheme == Uri.UriSchemeHttps;

Використання:

string url = "htts://adasd.xc.";
if(url.CheckUrlValid())
{
  //valid process
}

Це не здається для обробки URL-адрес www. IE: www.google.com показано як недійсний.
Заубер Парацельс

6
@ZauberParacelsus "www.google.com" недійсний. URL середній повинен починатися з «HTTP», «FTP», «файл» і т.д. рядки повинні бути «HTTP: // www.google.com» без простору
Ерчін Dedeoglu

1
Сьогодні параметр out може внести поліпшенняUri.TryCreate(source, UriKind.Absolute, out Uri uriResult) && uriResult.Scheme == Uri.UriSchemeHttps
GoClimbColorado

11

Всі відповіді тут або дозволити URL - адреса з іншими схемами (наприклад, file://, ftp://) або відхилити легким для читання URL , які не починаються з http://або https://(наприклад, www.google.com) , які не дуже добре при роботі з вводиться користувачем .

Ось як я це роблю:

public static bool ValidHttpURL(string s, out Uri resultURI)
{
    if (!Regex.IsMatch(s, @"^https?:\/\/", RegexOptions.IgnoreCase))
        s = "http://" + s;

    if (Uri.TryCreate(s, UriKind.Absolute, out resultURI))
        return (resultURI.Scheme == Uri.UriSchemeHttp || 
                resultURI.Scheme == Uri.UriSchemeHttps);

    return false;
}

Використання:

string[] inputs = new[] {
                          "https://www.google.com",
                          "http://www.google.com",
                          "www.google.com",
                          "google.com",
                          "javascript:alert('Hack me!')"
                        };
foreach (string s in inputs)
{
    Uri uriResult;
    bool result = ValidHttpURL(s, out uriResult);
    Console.WriteLine(result + "\t" + uriResult?.AbsoluteUri);
}

Вихід:

True    https://www.google.com/
True    http://www.google.com/
True    http://www.google.com/
True    http://google.com/
False

1
Це дозволяє провести окремі слова, такі як "mooooooooo", але вжиті разом із Uri.IsWellFormedUriString може бути корисним
Epirocks

@Epirocks Це хороший момент. Проблема http://moooooooooв тому, що насправді є дійсним Урі. Отже, ви не можете перевірити їх Uri.IsWellFormedUriStringпісля вставки "http: //", і якщо ви перевірите це раніше, все, що не має, Schemeбуде відхилено. Можливо, що ми можемо зробити, це ми перевіримо s.Contains('.')замість цього.
Ахмед Абдельхамед

moooooo сам по собі не схожий на URL, оскільки у нього немає протоколу. Що я зробив, - зняти ваш дзвінок з відповідним регулярним виразом, і && написав це також із IsWellFormedUriString.
Епіроки

@Epirocks Рівно! Проблема полягає в тому, що якщо ви використовуєте IsWellFormedUriStringперед додаванням http://, ви, в кінцевому підсумку, відхиляєте такі речі, як google.comі якщо ви будете використовувати їх після додавання http://, вона все одно поверне справжнє значення для http://mooooooooo. Ось чому я запропонував перевірити, чи містить рядок .замість цього.
Ахмед Абдельхамед

для мене все добре, я не хочу приймати URL без http або https на ньому. Тому я спочатку використовую IsWellFormedUriString, а потім використовую вашу функцію без регулярного вираження. bool bResult = (Uri.IsWellFormedUriString (s, UriKind.Absolute) && ValidHttpURL (s, out uriResult)); Спасибі
Епірокс


3

Спробуйте:

bool IsValidURL(string URL)
{
    string Pattern = @"^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$";
    Regex Rgx = new Regex(Pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
    return Rgx.IsMatch(URL);
}

Він прийме такий URL:

  • http (s): //www.example.com
  • http (s): //stackoverflow.example.com
  • http (s): //www.example.com/page
  • http (s): //www.example.com/page? id = 1 & product = 2
  • http (s): //www.example.com/page#start
  • http (s): //www.example.com: 8080
  • http (s): //127.0.0.1
  • 127.0.0.1
  • www.example.com
  • example.com

2

Це поверне bool:

Uri.IsWellFormedUriString(a.GetAttribute("href"), UriKind.Absolute)

2
Я думаю, що ОП спеціально згадано, йому не подобається Uri.IsWellFormedUriString, оскільки це відповідає дійсності для файлових шляхів. Чи є у вас рішення цієї проблеми?
Ісантіпов

1
Uri uri = null;
if (!Uri.TryCreate(url, UriKind.Absolute, out uri) || null == uri)
    return false;
else
    return true;

Ось urlрядок, який ви повинні перевірити.


3
null == Перевірка URL-адреси жахливо відмінна
JSON

0
bool passed = Uri.TryCreate(url, UriKind.Absolute, out Uri uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps)

Ваша відповідь надійшла в повідомленнях нижчої якості. Будь ласка, надайте пояснення, навіть якщо ваш код пояснюється самостійно.
Харша Біяні
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.