首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

HttpWebRequest POST HTTPS 失敗:憑證驗證與協議版本排查

     編輯:程式設計綜合問答

錯誤現象

HTTP 正常,HTTPS 在 GetRequestStream() 拋出「無法連接到遠程服務器」。已設置 ServerCertificateValidationCallback 返回 true。

排查步驟

  1. 驗證服務端可用性:瀏覽器/Postman/curl 直接 POST https://112.74.109.190/tniol-api/pos/login,確認接口正常。
  2. 檢查 TLS 版本:.NET Framework 4.0-4.5 默認不啟用 TLS 1.2。添加:
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
    
  3. IP 直連 HTTPS 的 SNI 問題:服務器可能配置多域名共用 IP,需設置 Host 標頭並啟用 SNI:
    request.Host = "api.example.com"; // 真實域名
    // .NET 4.5+ 自動支援 SNI
    
  4. 憑證鏈不信任:若服務器使用自簽名/內網 CA,需將根證書導入受信任根存儲,或回調中檢查 errors 參數決定是否接受。

最小可行代碼

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback += (s, cert, chain, errors) => true;

var request = (HttpWebRequest)WebRequest.Create("https://112.74.109.190/tniol-api/pos/login");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Host = "api.example.com"; // 若有域名

using (var writer = new StreamWriter(request.GetRequestStream())) {
    writer.Write("user_name=sapi&password=123");
}

using (var response = (HttpWebResponse)request.GetResponse())
using (var reader = new StreamReader(response.GetResponseStream())) {
    Console.WriteLine(reader.ReadToEnd());
}

現代替代方案

強烈建議遷移至 HttpClient (.NET Core/5+ 原生,Framework 需 NuGet System.Net.Http):

var handler = new HttpClientHandler {
    ServerCertificateCustomValidationCallback = (msg, cert, chain, errors) => true
};
using var client = new HttpClient(handler);
var content = new FormUrlEncodedContent(new[] {
    new KeyValuePair("user_name", "sapi"),
    new KeyValuePair("password", "123")
});
var resp = await client.PostAsync("https://...", content);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved