Làm cách nào để kiểm tra xem một chuỗi có phải là URL HTTP hợp lệ không?


251

Có các phương thức Uri.IsWellFormedUriStringUri.TryCreate, nhưng dường như chúng trả về truecác đường dẫn tệp, v.v.

Làm cách nào để kiểm tra xem một chuỗi có phải là URL HTTP hợp lệ (không nhất thiết phải hoạt động) cho mục đích xác thực đầu vào không?


Không sử dụng regex.IsMatch để xác thực Url. Có thể giết chết cpu. stackoverflow.com/questions/31227785/ từ
inesmar

Câu trả lời:


452

Hãy thử điều này để xác thực các URL HTTP ( uriNamelà URI bạn muốn kiểm tra):

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

Hoặc, nếu bạn muốn chấp nhận cả URL HTTP và HTTPS là hợp lệ (theo nhận xét của J0e3gan):

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

6
Điều này có nên đọc uriResult.Scheme thay vì uriName.Scheme? Tôi đang sử dụng quá tải để TryCreate lấy String thay vì Uri làm tham số đầu tiên.

7
Bạn có thể muốn thêm nhiều điều kiện hơn vào uriResult.Scheme == ... Cụ thể https. Nó phụ thuộc vào những gì bạn cần điều này, nhưng thay đổi nhỏ này là tất cả những gì tôi cần để nó hoạt động hoàn hảo với tôi.
Fiarr

11
Để rõ ràng theo nhận xét của @ Fiarr, "thay đổi nhỏ" cần thiết cho tài khoản HTTPS ngoài URL HTTP là:bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps;
J0e3gan

3
Cách này không thành công cho URL như abcde . Nó nói rằng đây là một URL hợp lệ.
Kailash P

7
Có vẻ như kỹ thuật này thất bại 22 trong số 75 thử nghiệm dotnetfiddle.net/XduN3A
whitneyland

98

Phương pháp này hoạt động tốt cả trong http và https. Chỉ một dòng :)

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

MSDN: IsWellFormedUriString


13
Điều này sẽ trở thành sự thật cho những người không-HTTP URI (tức là bất kỳ chương trình khác như file://hay ldap://giải pháp này nên được kết hợp với một tấm séc so với kế hoạch -. Ví dụif (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) ...
Squiggle

Đây có phải là RFC3986 tuân thủ?
Marcus

3
@Squiggle Đó chính xác là những gì tôi muốn kiểm tra, mọi thứ kể từ khi tôi tạo Trình tải xuống. Vì vậy, câu trả lời này là phương pháp tốt nhất cho tôi.
Beyondo

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

Sử dụng:

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

CẬP NHẬT: (một dòng mã) Cảm ơn @GoClimbColorado

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

Sử dụng:

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

Điều này không xuất hiện để xử lý các url www. IE: www.google.com được hiển thị là không hợp lệ.
Zauber Paracelsus

6
@ZauberParacelsus "www.google.com" không hợp lệ. Nghĩa là URL phải bắt đầu bằng chuỗi "http", "ftp", "file", v.v. nên là "http: // www.google.com" không có dấu cách
Erçin Dedeoğlu

1
Hôm nay, tham số out có thể cải thiệnUri.TryCreate(source, UriKind.Absolute, out Uri uriResult) && uriResult.Scheme == Uri.UriSchemeHttps
GoClimbColorado

11

Tất cả các câu trả lời ở đây hoặc là cho phép các URL với các chương trình khác (ví dụ, file://, ftp://) hoặc từ chối URL con người có thể đọc được mà không bắt đầu với http://hoặc https://(ví dụ www.google.com) mà là không tốt khi giao dịch với đầu vào người sử dụng .

Đây là cách tôi làm điều đó:

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

Sử dụng:

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

Đầu ra:

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

1
Điều này cho phép thông qua các từ đơn như "mooooooooo" nhưng được sử dụng cùng với Uri.IsWellFormedUriString có thể tốt
Epirocks 18/03/19

@Epirocks Đó là một điểm tốt. Vấn đề là http://moooooooootrên thực tế, một Uri hợp lệ. Do đó, bạn không thể kiểm tra Uri.IsWellFormedUriStringsau khi chèn "http: //" và nếu bạn kiểm tra trước đó, bất cứ điều gì không có Schemesẽ bị từ chối. Có lẽ những gì có thể được thực hiện là chúng ta kiểm tra s.Contains('.')thay thế.
Ahmed Abdelhameed

moooooo tự nó không giống như một url vì nó không có giao thức trên đó. Những gì tôi đã làm là loại bỏ cuộc gọi kết hợp regex của bạn và && 'ed với IsWellFormedUriString.
Epirocks

@Epirocks Chính xác! Vấn đề là nếu bạn sử dụng IsWellFormedUriStringtrước khi thêm http://, cuối cùng bạn sẽ từ chối những thứ như google.comvà nếu bạn sử dụng nó sau khi thêm http://, nó vẫn sẽ trở lại đúng http://mooooooooo. Đó là lý do tại sao tôi đề nghị kiểm tra xem chuỗi có chứa .thay thế không.
Ahmed Abdelhameed

Điều đó tốt cho tôi dù sao tôi cũng không muốn chấp nhận một url mà không có http hoặc https trên đó. Vì vậy, tôi sử dụng IsWellFormedUriString trước, sau đó sử dụng chức năng của bạn mà không cần regex. bool bResult = (Uri.IsWellFormedUriString (s, UriKind.Absolute) && ValidHttpURL (s, out uriResult)); Cảm ơn
Epirocks 20/03/19

5

Sau khi Uri.TryCreatebạn có thể kiểm tra Uri.Schemexem nó có HTTP (s) không.


3

Hãy thử điều đó:

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

Nó sẽ chấp nhận URL như thế:

  • http (s): //www.example.com
  • http (s): //stackoverflow.example.com
  • http (s): //www.example.com/page
  • http (s): //www.example.com/page? id = 1 & sản phẩm = 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

Điều này sẽ trả về bool:

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

2
Tôi nghĩ OP đã đề cập cụ thể, anh ấy không thích Uri.IsWellFormedUriString vì nó đúng với đường dẫn tệp. Bạn có một giải pháp cho vấn đề này?
Isantipov

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

Đây urllà chuỗi bạn phải kiểm tra.


3
null == kiểm tra url được đánh giá khủng khiếp
JSON

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

Câu trả lời của bạn đến trong bài viết chất lượng thấp hơn. Vui lòng cung cấp một số giải thích mặc dù mã của bạn là tự giải thích.
Harsha Biyani
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.