Как проверить, является ли строка действительным HTTP-URL?


251

Есть в Uri.IsWellFormedUriStringи Uri.TryCreateметоды, но они , кажется , чтобы вернуться trueна пути к файлам и т.д.

Как проверить, является ли строка действительным (не обязательно активным) HTTP-URL для проверки входных данных?


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

Ответы:


452

Попробуйте это проверить HTTP-URL ( uriNameэто URI, который вы хотите проверить):

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

Или, если вы хотите принять действительные URL-адреса HTTP и HTTPS (согласно комментарию 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 в дополнение к URL-адресам HTTP:bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps;
— J0e3gan

3
этот путь не работает для URL, как abcde . Это говорит, что это действительный URL.
— Кайлаш П

7
Похоже, что эта техника не проходит 22 из 75 тестов dotnetfiddle.net/XduN3A
— whitneyland

98

Этот метод отлично работает как в http и https. Всего одна строчка :)

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

MSDN: IsWellFormedUriString


13
Это возвращает истину для не-HTTP URI , (то есть какой - либо другой схемы , такие как file://или ldap://это решение должно быть соединено с чеком против схемы -. Напримерif (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) ...
— закорючка

Соответствует ли это RFC3986?
— Маркус

3
@Squiggle Это именно то, что я хочу, чтобы он проверил, все, так как я делаю Downloader. Так что этот ответ - лучший метод для меня.
— Бейондо

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", "file" и т. Д. Строка должна быть без пробела "http: // www.google.com"
— Erçin Dedeoğlu

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

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. Таким образом, вы не можете проверить Uri.IsWellFormedUriStringпосле вставки «http: //», и если вы проверяете его раньше, все, что не имеет, Schemeбудет отклонено. Может быть, то, что можно сделать, это проверить s.Contains('.')вместо этого.
— Ахмед Абдельхамид

Само по себе moooooo не выглядит как URL, так как на нем нет протокола. Что я сделал, так это снял ваш вызов на совпадение с регулярным выражением, и также отредактировал его с помощью IsWellFormedUriString.
— Epirocks

@ Epirocks Точно! Проблема в том, что если вы используете IsWellFormedUriStringперед добавлением http://, вы в конечном итоге отвергаете такие вещи, как, google.comи если вы используете его после добавления http://, он все равно будет возвращать true для http://mooooooooo. Вот почему я предложил проверить, содержит ли строка .вместо этого.
— Ахмед Абдельхамид

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


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 (ы): //www.example.com
  • HTTP (ы): //stackoverflow.example.com
  • HTTP (ы): //www.example.com/page
  • HTTP (S): //www.example.com/page ID = 1 & продукт = 2
  • HTTP (ы): //www.example.com/page#start
  • HTTP (ы): //www.example.com: 8080
  • HTTP (ы): //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.