首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

C# 驗證 URL 有效性:格式檢查與即時連線測試

     編輯:ASP.NET 基礎

兩層驗證策略

URL 驗證應分為 格式檢查(客戶端/伺服器端同步)與 存活檢查(伺服器端發送 HTTP 請求)兩層,兼顧使用者體驗與資料品質。

1. 格式檢查:正規表示式

JavaScript 版(前端即時提示)

function isValidUrlFormat(str) {
    // 支援 http/https、域名/IP、選擇性連接埠、路徑、查詢字串
    const pattern = /^https?:\/\/(([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|(\d{1,3}\.){3}\d{1,3})(:\d+)?(\/[^\s]*)?$/i;
    return pattern.test(str.trim());
}

C# 版(後端二次防禦)

using System.Text.RegularExpressions;

public static bool IsValidUrlFormat(string url)
{
    if (string.IsNullOrWhiteSpace(url)) return false;
    // 與 JS 版同邏輯,確保前後端一致
    const string pattern = @"^https?://(([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|(\d{1,3}\.){3}\d{1,3})(:\d+)?(/[^\s]*)?$";
    return Regex.IsMatch(url.Trim(), pattern, RegexOptions.IgnoreCase);
}

2. 存活檢查:發送 HTTP HEAD 請求

僅檢查格式無法確認網址真正可存取。伺服器端可發送 HEAD 請求(不下載內文),依狀態碼判斷。

using System.Net;

public static bool IsUrlReachable(string url, int timeoutMs = 10000)
{
    if (!IsValidUrlFormat(url)) return false;

    // 自動補齊 scheme
    if (!url.StartsWith("https://", StringComparison.OrdinalIgnoreCase) &&
        !url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
        url = "https://" + url;

    try
    {
        var request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "HEAD";           // 僅取得標頭
        request.Timeout = timeoutMs;       // 10 秒逾時
        request.AllowAutoRedirect = true;  // 允許重導向
        request.UserAgent = "Mozilla/5.0 (compatible; UrlValidator/1.0)";

        using (var response = (HttpWebResponse)request.GetResponse())
        {
            // 2xx、3xx 視為成功(3xx 代表重導向但最終可達)
            return (int)response.StatusCode < 400;
        }
    }
    catch (WebException ex) when (ex.Response is HttpWebResponse resp)
    {
        // 4xx/5xx 也能拿到回應,視業務需求決定是否視為有效
        return (int)resp.StatusCode < 400;
    }
    catch
    {
        // DNS 失敗、連線逾時、SSL 錯誤等
        return false;
    }
}

整合使用範例

public JsonResult ValidateUrl(string inputUrl)
{
    if (!IsValidUrlFormat(inputUrl))
        return Json(new { valid = false, reason = "格式錯誤" });

    bool reachable = IsUrlReachable(inputUrl);
    return Json(new { valid = reachable, reason = reachable ? "OK" : "無法連線或回應異常" });
}

效能與安全考量

議題建議做法
大量並發驗證使用 HttpClient + SemaphoreSlim 限制並發數;或放入背景工作佇列非同步處理。
SSRF 風險禁止驗證內網 IP(10.x、172.16-31、192.168、127.0.0.1)、localhost、metadata 端點;僅允許公網域名。
重導向循環設定 request.MaxAutomaticRedirections = 5。
憑證錯誤若需忽略 SSL 錯誤(僅測試環境),可實作 ServerCertificateCustomValidationCallback(需 HttpClient)。

現代化替代:HttpClient 版本

private static readonly HttpClient _httpClient = new HttpClient
{
    Timeout = TimeSpan.FromSeconds(10),
    DefaultRequestHeaders = { UserAgent = { { "UrlValidator", "1.0" } } }
};

public static async Task IsUrlReachableAsync(string url)
{
    if (!IsValidUrlFormat(url)) return false;
    if (!url.StartsWith("http")) url = "https://" + url;

    try
    {
        using var request = new HttpRequestMessage(HttpMethod.Head, url);
        using var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
        return response.IsSuccessStatusCode || (int)response.StatusCode < 400;
    }
    catch { return false; }
}

總結

  • 格式檢查:前後端同步,攔截明顯錯誤,零成本。
  • 存活檢查:伺服器端 HEAD 請求,確保連結真實可用,防止垃圾連結汙染資料庫。
  • 安全第一:嚴防 SSRF,限制驗證目標為公網合法域名。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved