ASP.NET Core部署IIS后API调用失败及HTTPS调用HTTP API疑问
ASP.NET Core部署IIS后API调用连接失败问题排查及相关疑问
问题详情
本地运行ASP.NET Core项目时,API调用功能完全正常,但部署到IIS服务器后出现连接超时异常,具体报错信息:
"A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond."
对应的堆栈跟踪:
System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at AILS.Mobile.Base.Controllers.UtilController.GetPostRequest[T](String url, Object requestData, Boolean getReq)
API调用代码如下:
BaseResponse<T> responseResult = new BaseResponse<T>(); Type _obj = typeof(T); using (var client = new HttpClient()) { try { UriBuilder builder = new UriBuilder(!url.Contains("handshake") ? GetCookie(ASMobileConstant.CookiesKey.BaseURL) + url : url); HttpResponseMessage response = new HttpResponseMessage(); string content = string.Empty; if (getReq) { response = await client.GetAsync(builder.Uri, HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); content = await response.Content.ReadAsStringAsync(); response.Dispose(); } else { HttpContent httpContent = new StringContent(JsonSerializer.Serialize(requestData), System.Text.Encoding.UTF8, "application/json"); response = await client.PostAsync(builder.Uri, httpContent); content = await response.Content.ReadAsStringAsync(); response.Dispose(); } if (_obj != typeof(clsResponse)) { responseResult = new BaseResponse<T>(JsonSerializer.Deserialize<clsResponse>(content)); } else { responseResult = JsonSerializer.Deserialize<BaseResponse<T>>(content); } } catch (Exception ex) { responseResult.IsGood = false; responseResult.Message = ex.Message; myLogger.Error("catch {0}", ex.Message); myLogger.Error("catch {0}", ex.StackTrace); } finally { client.Dispose(); } }
调用目标API地址为http://xxx.ask.com/mobileapi/Login,通过POSTMAN手动测试该API完全正常,需排查IIS部署后的异常原因,同时咨询:HTTPS站点能否调用HTTP API?
排查方向
- IIS应用程序池权限:检查应用程序池的运行标识(如ApplicationPoolIdentity)是否具备访问目标API的权限。若目标API在同一服务器,需确保应用池身份能访问该站点;若为外部API,确认服务器防火墙允许出站请求到目标端口。
- 网络连通性验证:在服务器上执行
ping xxx.ask.com或tracert xxx.ask.com,测试DNS解析和网络链路是否通畅,确认服务器能正常连接到目标API的主机。 - 目标API的访问配置:检查目标API所在IIS站点的绑定设置,确保包含服务器的内网IP或正确的主机头,避免仅绑定localhost导致无法访问。同时确认目标API是否有IP白名单限制,服务器IP是否在允许范围内。
- HttpClient优化:代码中每次调用都创建并销毁HttpClient,可能引发连接池耗尽问题,建议改用单例模式或依赖注入方式复用HttpClient。另外,若服务器需通过代理访问外部网络,需为HttpClient配置代理参数。
- 混合内容与安全策略:若当前站点为HTTPS,服务器端HttpClient调用HTTP API本身不受浏览器混合内容限制,但需确认服务器是否有防火墙、组策略等安全配置禁止HTTPS站点发起HTTP出站请求。
HTTPS站点调用HTTP API的说明
HTTPS站点的服务器端使用HttpClient调用HTTP API是可行的,不受浏览器端混合内容规则的约束,但需注意以下几点:
- 确认服务器网络策略允许出站HTTP请求,避免防火墙或安全组拦截。
- 若目标API在同一服务器,检查IIS是否允许跨协议访问,部分安全配置可能限制HTTPS站点访问同服务器的HTTP站点。
- 从安全角度出发,建议将目标API升级为HTTPS,避免明文传输数据带来的安全风险。
内容的提问来源于stack exchange,提问作者JC YOUNG
相关产品推荐
相关产品推荐

