用 HttpClient 发 HEAD 请求最可靠,需复用实例、显式设 HttpMethod.Head、设 3–5 秒超时;遇 405 则降级 GET+Range: bytes=0-0;须区分 SocketException 类型并添加 User-Agent 头。

用 HttpClient 发 HEAD 请求最可靠
直接发 HEAD 是判断 URL 是否可达又不下载内容的正解,HttpClient 支持原生 HEAD 方法,比拼接字符串或伪造请求头靠谱得多。注意别用 WebClient 或老式 HttpWebRequest——它们对 HEAD 支持弱,容易误判 405 或超时。
-
HttpClient实例应复用(全局单例或 DI 注入),反复 new 会耗尽 socket - 必须显式设置
method = HttpMethod.Head,不能只改请求头里的Method - 某些服务器(如 GitHub Pages)默认禁 HEAD,返回 405;这时得 fallback 到 GET +
Range: bytes=0-0 - 超时建议设为 3–5 秒:
client.Timeout = TimeSpan.FromSeconds(4),太短误伤高延迟正常站,太长卡主线程
var client = new HttpClient(); var request = new HttpRequestMessage(HttpMethod.Head, "https://example.com"); var response = await client.SendAsync(request); bool isValid = response.IsSuccessStatusCode || response.StatusCode == HttpStatusCode.NotFound;
遇到 405 Method Not Allowed 怎么办
这不是网址无效,是目标服务器拒绝 HEAD。常见于静态托管服务或 Nginx 默认配置。硬扛 405 会导致误判,得主动降级策略。
- 捕获
HttpRequestException并检查response.StatusCode == HttpStatusCode.MethodNotAllowed - 降级用 GET 请求,但加
Range: bytes=0-0头,让服务器只返回响应头不传正文 - 务必加
request.Headers.Accept = "application/json,text/html,*/*",避免因 Accept 头缺失被 406 拦截 - 慎用
HEAD /favicon.ico做探测——很多 CDN 对 favicon 缓存激进,返回 200 但主站已宕
DNS 或连接层失败 ≠ 网址无效
HttpRequestException 内部可能是 SocketException(如 DNS 解析失败、连接被拒),这类错误和 HTTP 状态码无关,不能简单当“网址无效”处理。
- 区分异常类型:
ex.InnerException is SocketException se && se.SocketErrorCode == SocketError.HostNotFound→ 域名根本不存在 -
se.SocketErrorCode == SocketError.ConnectionRefused→ 服务端口关闭或防火墙拦截,网址语法有效但服务不可达 - 不要把
TaskCanceledException当作网址错误——大概率是超时,重试 1 次更合理 - 本地 hosts 劫持、代理设置、IPv6 双栈故障都可能导致连接失败,和 URL 字符串本身无关
别忽略 HTTPS 重定向和证书问题
用户输的是 http://,但网站强制跳转 https://,此时 HEAD 请求可能被 301/302 中断,HttpClient 默认不自动跟随重定向(尤其 HEAD),导致误判为失败。
- 设置
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0"),部分站点对无 UA 的 HEAD 返回 403 - 若需跟随跳转,手动处理
Location响应头,别依赖AllowAutoRedirect = true(HEAD 重定向语义模糊) - 自签名证书或过期证书会让请求直接抛
HttpRequestException,需配置HttpClientHandler.ServerCertificateCustomValidationCallback容错(仅测试环境) - 纯验证连通性时,用
HttpClientHandler.MaxAutomaticRedirections = 0更干净,靠状态码+Location 判断是否可访问
SocketException 的细分判断和 User-Agent 头——没它,不少 CDN 和 WAF 直接静默丢包,看着像超时,其实连三次握手都没完成。


















