วิธีการตรวจสอบว่าสตริงเป็น URL HTTP ที่ถูกต้อง?


251

มีUri.IsWellFormedUriStringและUri.TryCreateวิธีการ แต่พวกเขาดูเหมือนจะกลับtrueสำหรับเส้นทางไฟล์ ฯลฯ

ฉันจะตรวจสอบได้อย่างไรว่าสตริงนั้นเป็น URL HTTP ที่ถูกต้อง (ไม่จำเป็นต้องใช้งาน) สำหรับการตรวจสอบความถูกต้องของอินพุต


อย่าใช้ regex.IsMatch เลยเพื่อตรวจสอบ Url สามารถฆ่าซีพียูได้ stackoverflow.com/questions/31227785/…
inesmar

คำตอบ:


452

ลองใช้วิธีนี้เพื่อตรวจสอบความถูกต้องของ URL 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);

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 ที่ถูกต้อง
Kailash P

7
ดูเหมือนว่าเทคนิคนี้ล้มเหลว 22 จาก 75 การทดสอบdotnetfiddle.net/XduN3A
whitneyland

98

วิธีนี้ใช้ได้ดีทั้งใน http และ https แค่บรรทัดเดียว :)

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

MSDN: IsWellFormedUriString


13
สิ่งนี้จะส่งกลับค่าจริงสำหรับ URI ที่ไม่ใช่ HTTP (เช่นรูปแบบอื่น ๆเช่นfile://หรือldap://วิธีการนี้ควรควบคู่กับการตรวจสอบกับรูปแบบ - เช่นif (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) ...
Squiggle

RFC3986 นี้สอดคล้องหรือไม่?
มาร์คัส

3
@ Squiggle นั่นคือสิ่งที่ฉันต้องการตรวจสอบทุกอย่างตั้งแต่ฉันสร้างไฟล์ ดังนั้นคำตอบนี้เป็นวิธีที่ดีที่สุดสำหรับฉัน
Beyondo

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 แสดงว่าไม่ถูกต้อง
Zauber Paracelsus

6
@ZauberParacelsus "www.google.com" ไม่ถูกต้อง ค่าเฉลี่ย URL ควรเริ่มต้นด้วย "http", "ftp", "file" ฯลฯ สตริงควรเป็น "http: // www.google.com" โดยไม่มีที่ว่าง
ErçinDedeoğlu

1
วันนี้พารามิเตอร์ out สามารถทำการปรับปรุงได้Uri.TryCreate(source, UriKind.Absolute, out Uri uriResult) && uriResult.Scheme == Uri.UriSchemeHttps
GoClimbColorado

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 เพราะมันไม่มีโปรโตคอล สิ่งที่ฉันทำคือนำสายการจับคู่ regex ของคุณและ && แก้ไขด้วย IsWellFormedUriString เช่นกัน
Epirocks

@Epirocks แน่นอน! ปัญหาคือว่าถ้าคุณใช้IsWellFormedUriStringก่อนที่จะเพิ่มhttp://คุณจะจบลงด้วยการปฏิเสธสิ่งที่ชอบgoogle.comและถ้าคุณใช้มันหลังจากที่เพิ่มก็ยังจะกลับจริงสำหรับhttp:// http://moooooooooนั่นเป็นเหตุผลที่ฉันแนะนำให้ตรวจสอบว่าสตริงมี.แทน
Ahmed Abdelhameed

ไม่เป็นไรสำหรับฉันแล้วฉันไม่ต้องการรับ URL ที่ไม่มี http หรือ https ดังนั้นฉันใช้ IsWellFormedUriString ก่อนจากนั้นใช้ฟังก์ชันของคุณโดยไม่ต้อง regex bool bResult = (Uri.IsWellFormedUriString (s, UriKind.Absolute) && ValidHttpURL (s, ออก uriResult)); ขอบคุณ
Epirocks


4

ลองที่:

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 & สินค้า = 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

สิ่งนี้จะคืนค่าบูล:

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

2
ฉันคิดว่า OP ที่ระบุไว้โดยเฉพาะเขาไม่ชอบ Uri.IsWellFormedUriString เพราะมันให้เส้นทางที่เป็นจริง คุณมีทางออกสำหรับปัญหานี้หรือไม่?
Isantipov

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

นี่urlคือสตริงที่คุณต้องทดสอบ


3
null == ตรวจสอบ url เป็น reduntant ที่น่ากลัว
JSON

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

คำตอบของคุณมาในโพสต์คุณภาพต่ำ โปรดให้คำอธิบายบางอย่างแม้ว่ารหัสของคุณจะอธิบายด้วยตนเอง
Harsha Biyani
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.