【问题标题】:How to check whether a string is a valid HTTP URL?如何检查字符串是否是有效的 HTTP URL?
【发布时间】:2011-11-26 14:09:39
【问题描述】:

Uri.IsWellFormedUriStringUri.TryCreate 方法,但它们似乎返回 true 用于文件路径等。

如何检查字符串是否为有效(不一定是活动的)HTTP URL 以进行输入验证?

【问题讨论】:

标签: c# .net validation url uri


【解决方案1】:

Uri.TryCreate 之后,您可以检查Uri.Scheme 以查看它是否为 HTTP(s)。

【讨论】:

    【解决方案2】:

    试试这个来验证 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);
    

    【讨论】:

    • 应该读 uriResult.Scheme 而不是 uriName.Scheme?我正在使用 TryCreate 的重载,它采用 String 而不是 Uri 作为它的第一个参数。
    • 您可能希望向 uriResult.Scheme 添加更多条件 == ... 特别是 https。这取决于您需要它来做什么,但我只需要这个小改动就可以让它完美地为我工作。
    • 根据@Fiarr 的评论要明确,除了 HTTP URL 之外,考虑 HTTPS 所需的“小改动”是:bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps;
    • 这种方式对于像 abcde 这样的 URL 会失败。它说这是一个有效的 URL。
    • 看起来这项技术在 75 次测试中有 22 次失败 dotnetfiddle.net/XduN3A
    【解决方案3】:

    这将返回 bool:

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

    【讨论】:

    • 我认为 OP 特别提到,他不喜欢 Uri.IsWellFormedUriString ,因为它为文件路径提供了 true 。你有解决这个问题的办法吗?
    【解决方案4】:
    Uri uri = null;
    if (!Uri.TryCreate(url, UriKind.Absolute, out uri) || null == uri)
        return false;
    else
        return true;
    

    这里url是你要测试的字符串。

    【讨论】:

    • null == url 检查非常冗余
    【解决方案5】:
        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
    }
    

    【讨论】:

    • 这似乎无法处理 www 网址。 IE:www.google.com 显示为无效。
    • @ZauberParacelsus "www.google.com" 无效。 URL 的意思应该以“http”、“ftp”、“file”等开头。字符串应该是“http://www.google.com”,没有空格
    • 今天out参数可以改进Uri.TryCreate(source, UriKind.Absolute, out Uri uriResult) && uriResult.Scheme == Uri.UriSchemeHttps
    • 这不适用于 abc、tassdds 等随机字符串。
    【解决方案6】:

    此方法在 http 和 https 中都可以正常工作。就一行:)

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

    MSDN:IsWellFormedUriString

    【讨论】:

    • 这将为非 HTTP URI 返回 true(即 any other scheme,例如 file://ldap://。此解决方案应结合对方案的检查 - 例如 if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) ...跨度>
    • 这符合 RFC3986 吗?
    • @Squiggle 这正是我希望它检查的内容,一切,因为我正在制作下载器。所以,这个答案对我来说是最好的方法。
    • 问题是 IsWellFormedUriString 将末尾的空格呈现为 URL 的有效部分。不,它不认为它们是 %20s,因为在空格后添加有效符号会导致 URL 无效:“a” - 有效 “a” - 有效?! “a a” - 无效?!?
    • 对于简单的字符串 URL 验证,我认为这更好,如果您使用 "http:\\test.com" 而不是 "test.com" 它只会返回 false 而 .TryCreate 足够聪明更正无效的斜杠。但在我的情况下,这个字符串在其他地方被用于进行 REST 调用并导致异常。
    【解决方案7】:

    此处的所有答案要么允许使用其他方案的 URL(例如,file://ftp://),要么拒绝不以 http://https:// 开头的人类可读的 URL(例如,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
    

    【讨论】:

    • 这可以让诸如“mooooooooo”之类的单个词通过,但与 Uri.IsWellFormedUriString 结合使用可能会很好
    • @Epirocks 这是一个很好的观点。问题是 http://mooooooooo 实际上是一个有效的 Uri。因此,您无法在插入“http://”后检查Uri.IsWellFormedUriString,如果您之前检查过,任何没有Scheme 的内容都将被拒绝。也许可以做的是我们检查s.Contains('.')
    • moooooo 本身看起来不像 url,因为它没有协议。我所做的是取出您的正则表达式匹配调用,并使用 IsWellFormedUriString 对其进行 &&'ed。
    • @Epirocks 没错!问题是如果你在添加http://之前使用IsWellFormedUriString,你最终会拒绝像google.com这样的东西,如果你在添加http://之后使用它,它仍然会为http://mooooooooo返回true .这就是为什么我建议检查字符串是否包含.
    • 这对我来说很好,我不想接受没有 http 或 https 的 url。所以我首先使用 IsWellFormedUriString,然后使用没有正则表达式的函数。 bool bResult = (Uri.IsWellFormedUriString(s, UriKind.Absolute) && ValidHttpURL(s, out uriResult));谢谢
    【解决方案8】:

    作为使用正则表达式的替代方法,此代码根据 OP 使用 Uri.TryCreate,但随后还会检查结果以确保其 Scheme 是 http 或 https 之一:

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

    【讨论】:

    • 您的回答来自质量较低的帖子。即使您的代码是不言自明的,也请提供一些解释。
    【解决方案9】:

    试试看:

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-10
      • 2013-02-13
      • 2011-06-17
      • 2018-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多