Comment vérifier si une chaîne est une URL HTTP valide?


251

Il existe les méthodes Uri.IsWellFormedUriStringet Uri.TryCreate, mais elles semblent revenir truepour les chemins de fichiers, etc.

Comment vérifier si une chaîne est une URL HTTP valide (pas nécessairement active) à des fins de validation d'entrée?


N'utilisez pas du tout regex.IsMatch pour valider l'URL. Peut tuer le processeur. stackoverflow.com/questions/31227785/…
inesmar

Réponses:


452

Essayez ceci pour valider les URL HTTP ( uriNameest l'URI que vous souhaitez tester):

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

Ou, si vous souhaitez accepter les URL HTTP et HTTPS comme valides (selon le commentaire de J0e3gan):

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

6
Cela devrait-il lire uriResult.Scheme au lieu de uriName.Scheme? J'utilise la surcharge de TryCreate qui prend String au lieu d'Uri comme premier paramètre.

7
Vous voudrez peut-être ajouter plus de conditions à uriResult.Scheme == ... spécifiquement https. Cela dépend de ce dont vous avez besoin, mais ce petit changement était tout ce dont j'avais besoin pour que cela fonctionne parfaitement pour moi.
Fiarr

11
Pour être clair selon le commentaire de @ Fiarr, le "petit changement" nécessaire pour tenir compte du HTTPS en plus des URL HTTP est:bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps;
J0e3gan

3
cette façon échoue pour les URL comme abcde . Il indique qu'il s'agit d'une URL valide.
Kailash P

7
On dirait que cette technique échoue 22 des 75 tests dotnetfiddle.net/XduN3A
whitneyland

98

Cette méthode fonctionne bien à la fois dans http et https. Une seule ligne :)

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

MSDN: IsWellFormedUriString


13
Cela retournera vrai pour les URI non HTTP (c'est-à-dire tout autre schéma tel que file://ou ldap://. Cette solution doit être couplée avec une vérification par rapport au schéma - par exempleif (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) ...
Squiggle

Ce RFC3986 est-il conforme?
Marcus

3
@Squiggle C'est exactement ce que je veux qu'il vérifie, tout depuis que je fais un Downloader. Donc, cette réponse est la meilleure méthode pour moi.
Beyondo

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

Usage:

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

MISE À JOUR: (une seule ligne de code) Merci @GoClimbColorado

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

Usage:

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

Cela ne semble pas gérer les URL www. IE: www.google.com est indiqué comme non valide.
Zauber Paracelsus

6
@ZauberParacelsus "www.google.com" n'est pas valide. La moyenne de l'URL doit commencer par "http", "ftp", "file" etc. La chaîne doit être "http: // www.google.com" sans espace
Erçin Dedeoğlu

1
Aujourd'hui, le paramètre out peut apporter une améliorationUri.TryCreate(source, UriKind.Absolute, out Uri uriResult) && uriResult.Scheme == Uri.UriSchemeHttps
GoClimbColorado

11

Toutes les réponses ici permettent soit des URL avec d' autres systèmes (par exemple file://, ftp://) ou rejeter des URL lisibles par l' homme qui ne commencent pas http://ou https://(par exemple www.google.com) qui est pas bon lorsqu'il s'agit d'entrées utilisateur .

Voici comment je le fais:

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

Usage:

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

Production:

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

1
Cela laisse passer des mots uniques comme "mooooooooo" mais utilisé en conjonction avec Uri.IsWellFormedUriString pourrait être bon
Epirocks

@Epirocks C'est un bon point. Le problème est qu'il http://mooooooooos'agit en fait d'un Uri valide. Par conséquent, vous ne pouvez pas vérifier Uri.IsWellFormedUriStringaprès avoir inséré "http: //" et si vous le vérifiez avant, tout ce qui n'a pas de Schemesera rejeté. Peut-être que ce qui peut être fait est de vérifier à la s.Contains('.')place.
Ahmed Abdelhameed

moooooo en lui-même ne ressemble pas à une URL car il n'a pas de protocole dessus. Ce que j'ai fait, c'est retirer votre appel de correspondance d'expressions régulières, et l'avez également édité avec IsWellFormedUriString.
Epirocks

@Epirocks Exactement! Le problème est que si vous utilisez IsWellFormedUriStringavant d'ajouter le http://, vous finirez par rejeter des choses comme google.comet si vous l'utilisez après avoir ajouté le http://, il restera vrai http://mooooooooo. C'est pourquoi j'ai suggéré de vérifier si la chaîne contient .plutôt un .
Ahmed Abdelhameed

c'est bien pour moi de toute façon je ne veux pas accepter une URL sans http ou https dessus. J'utilise donc d'abord IsWellFormedUriString, puis j'utilise votre fonction sans regex. bool bResult = (Uri.IsWellFormedUriString (s, UriKind.Absolute) && ValidHttpURL (s, out uriResult)); Merci
Epirocks


3

Essayez ça:

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

Il acceptera une URL comme celle-ci:

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

2

Cela retournerait bool:

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

2
Je pense que l'OP spécifiquement mentionné, il n'aime pas Uri.IsWellFormedUriString car cela donne le vrai pour les chemins de fichiers. Avez-vous une solution à ce problème?
Isantipov

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

Voici urlla chaîne que vous devez tester.


3
null == le contrôle d'URL est horriblement redondant
JSON

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

Votre réponse est venue dans des messages de qualité inférieure. Veuillez fournir des explications même si votre code est explicite.
Harsha Biyani
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.