Jak sprawdzić, czy ciąg jest prawidłowym adresem URL HTTP?


251

Istnieją metody Uri.IsWellFormedUriStringi Uri.TryCreate, ale wydaje się, że wracają truedo ścieżek plików itp.

Jak sprawdzić, czy ciąg znaków jest poprawnym (niekoniecznie aktywnym) adresem URL HTTP do celów sprawdzania poprawności danych wejściowych?


Nie używaj regex.IsMatch w celu sprawdzenia adresu URL. Może zabić procesor. stackoverflow.com/questions/31227785/…
inesmar

Odpowiedzi:


451

Wypróbuj to, aby sprawdzić poprawność adresów URL HTTP ( uriNamejest to URI, który chcesz przetestować):

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

Lub jeśli chcesz zaakceptować zarówno adresy URL HTTP, jak i HTTPS jako prawidłowe (na komentarz J0e3gan):

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

6
Czy powinien to czytać uriResult.Scheme zamiast uriName.Scheme? Używam przeciążenia do TryCreate, które bierze String zamiast Uri jako pierwszego parametru.

7
Możesz dodać więcej warunków do uriResult.Scheme == ... W szczególności https. To zależy od tego, czego potrzebujesz, ale ta mała zmiana była wszystkim, czego potrzebowałem, aby działała idealnie dla mnie.
Fiarr

11
Aby być jasnym w komentarzu @ Fiarra, „mała zmiana” potrzebna do uwzględnienia HTTPS oprócz adresów URL HTTP to:bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps;
J0e3gan

3
ten sposób kończy się niepowodzeniem dla adresu URL takiego jak abcde . Mówi, że to jest prawidłowy adres URL.
Kailash P

7
Wygląda na to, że ta technika kończy się niepowodzeniem 22 z 75 testów dotnetfiddle.net/XduN3A
whitneyland

98

Ta metoda działa dobrze zarówno w http, jak i https. Tylko jedna linia :)

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

MSDN: IsWellFormedUriString


13
Zwróci to wartość true dla identyfikatorów URI innych niż HTTP (tj. Każdego innego schematu, takiego jak file://lub ldap://. To rozwiązanie powinno być połączone z kontrolą względem schematu - np.if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) ...
Squiggle

Czy to jest zgodne z RFC3986?
Marcus

3
@ Quiggle To dokładnie to, co chcę sprawdzić, wszystko, odkąd tworzę Downloader. Ta odpowiedź jest dla mnie najlepszą metodą.
Beyondo

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

Stosowanie:

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

AKTUALIZACJA: (pojedynczy wiersz kodu) Dzięki @GoClimbColorado

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

Stosowanie:

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

To nie wydaje się obsługiwać adresów URL www. IE: www.google.com jest wyświetlany jako nieprawidłowy.
Zauber Paracelsus

6
@ZauberParacelsus „www.google.com” jest nieprawidłowy. Średni adres URL powinien zaczynać się od „http”, „ftp”, „plik” itp. Ciąg powinien być „http: // www.google.com” bez spacji
Erçin Dedeoğlu

1
Dzisiaj parametr out może poprawićUri.TryCreate(source, UriKind.Absolute, out Uri uriResult) && uriResult.Scheme == Uri.UriSchemeHttps
GoClimbColorado

11

Wszyscy tutaj odpowiedzi zezwolić URL z innymi systemami (np file://, ftp://) lub odrzucić URL czytelny dla człowieka, które nie zaczynają się http://lub https://(na przykład www.google.com), co nie jest dobre, gdy do czynienia z wejściami użytkownika .

Oto jak to robię:

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;
}

Stosowanie:

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);
}

Wynik:

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

1
Dzięki temu pojedyncze słowa, takie jak „mooooooooo”, ale użyte w połączeniu z Uri.IsWellFormedUriString mogą być dobre
Epirocks

@Epirocks To dobra uwaga. Problem polega na tym http://mooooooooo, że w rzeczywistości jest to prawidłowy Uri. Dlatego nie możesz sprawdzić Uri.IsWellFormedUriStringpo wstawieniu „http: //”, a jeśli zaznaczysz to wcześniej, wszystko, co nie ma, Schemezostanie odrzucone. Może to, co można zrobić, to sprawdzamy s.Contains('.')zamiast tego.
Ahmed Abdelhameed

moooooo sam w sobie nie wygląda na adres URL, ponieważ nie ma na nim protokołu. To, co zrobiłem, to wybranie twojego dopasowania do wyrażenia regularnego, a także && z IsWellFormedUriString.
Epirocks

@Epirocks Dokładnie! Problem polega na tym, że jeśli użyjesz IsWellFormedUriStringprzed dodaniem http://, ostatecznie odrzucisz takie rzeczy, google.coma jeśli użyjesz go po dodaniu http://, to nadal zwróci wartość true http://mooooooooo. Dlatego zasugerowałem sprawdzenie, czy ciąg zawiera .zamiast niego.
Ahmed Abdelhameed

to jest dla mnie w porządku, mimo to nie chcę akceptować adresu URL bez http lub https. Więc najpierw używam IsWellFormedUriString, a następnie używam twojej funkcji bez wyrażenia regularnego. bool bResult = (Uri.IsWellFormedUriString (s, UriKind.Absolute) && ValidHttpURL (s, out uriResult)); Dzięki
Epirocks


3

Spróbuj tego:

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

Przyjmie następujący adres URL:

  • http (s): //www.example.com
  • http (s): //stackoverflow.example.com
  • http (s): //www.example.com/strona
  • http (s): //www.example.com/page? id = 1 i 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
  • przyklad.com

2

Zwróci bool:

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

2
Myślę, że OP konkretnie wspomniał, że nie lubi Uri.IsWellFormedUriString, ponieważ daje to prawdę dla ścieżek plików. Czy masz rozwiązanie tego problemu?
Isantipov

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

Oto urlciąg, który musisz przetestować.


3
null == sprawdzenie adresu URL jest strasznie redundantne
JSON

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

Twoja odpowiedź nadeszła w postach niższej jakości. Podaj wyjaśnienie, nawet jeśli Twój kod jest zrozumiały.
Harsha Biyani
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.