HTTP 状态码 500,.net core CORS 和 HttpClient 错误

Posted

技术标签:

【中文标题】HTTP 状态码 500,.net core CORS 和 HttpClient 错误【英文标题】:HTTP status code 500, .net core CORS And HttpClient errors 【发布时间】:2018-05-09 11:22:43 【问题描述】:

我在 dotnet 核心中遇到了一些关于 CORS/HttpClient 的问题。首先,我的应用程序结构如下:

Webapp -> Microservice-Gateway -> multiple Microservices

如果我从我的 Web 应用程序进行 Ajax 调用

$.ajax(
        url: "https://[actual gateway Url]/customer/" + customerId,
        type: "GET",
        timeout: 60000,
        crossDomain: true,
        dataType: "json",
        success: data => 
            //...
        
    );

到网关服务器我有时会收到以下错误消息:

请求中没有“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://localhost:50595” 使用权。响应的 HTTP 状态代码为 500。

但是,如果我在内部进行调试,我的网关会抛出此错误:

System.Net.Http.HttpRequestException:发送时出错 请求。 ---> System.Net.Http.WinHttpException: 操作 超时

我尝试通过在网关和每个微服务中添加以下代码来解决第一个错误:

public void ConfigureServices(IServiceCollection services) 
        var corsBuilder = new CorsPolicyBuilder();
        corsBuilder.AllowAnyHeader();
        corsBuilder.AllowAnyMethod();
        corsBuilder.AllowAnyOrigin();
        corsBuilder.AllowCredentials();

        services.AddCors(options => 
            options.AddPolicy("SiteCorsPolicy", corsBuilder.Build());
        );
 //..
 
 public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
        app.UseCors("SiteCorsPolicy");
 //..
 

为了确保我还添加了

[EnableCors("SiteCorsPolicy")]

到每个控制器。 我试图通过在我的网关中创建一个 HttpClient 作为 Singleton 并修改以下属性来解决第二个问题:

var client = new HttpClient();
client.Timeout = new TimeSpan(0, 10, 0);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
services.AddSingleton(client);

我的网关发送这样的 HTTP 请求:

[HttpGet("id")]
public async Task<JsonResult> GetById(int id) 
    var response = await _client.GetAsync(new Uri(ServiceUrls.Customer + $"id"));

    if (!response.IsSuccessStatusCode)
        return new JsonResult(BadRequest($"(int)response.StatusCode: response.ReasonPhrase"));

    var customer = JsonConvert.DeserializeObject<CustomerViewModel>(await response.Content.ReadAsStringAsync());
    return new JsonResult(customer);

正如我所说,有时有效,有时无效。也许你可以给我一些想法什么是我的错误。提前致谢!

编辑:如果一次有多个来自 Webapp 的异步 ajax 调用,问题似乎会更频繁地出现。但这也可能只是一种感觉。

【问题讨论】:

你能分享一下你在哪里定义了你的“SiteCorsPolicy”政策@Simon? "options.AddPolicy("SiteCorsPolicy", corsBuilder.Build());"在第五个代码段 问题是 500 错误,与你的 CORS 配置无关。只是和大多数服务器一样,这个只是将 Access-Control-Allow-Origin 和其他自定义配置的响应头添加到 2xx 成功消息,而不是 5xx 和 4xx 错误。 谢谢@sideshowbarker!这将其缩小到 HttpClient。我多次读过 HttpClient 是线程安全的,这是错的吗?我真的想不出它失败的另一个原因。 ***.com/questions/11178220/… 似乎是关于 HttpClient 线程安全的规范答案。 【参考方案1】:

这可能与您的 CORS 设置无关。当发生错误时(例如使用 HttpClient 的 HTTP 调用),默认的异常处理程序中间件会删除所有响应标头并返回错误响应。这意味着您的策略添加的任何 CORS 标头都将被删除,因此您将收到有关“请求的资源上不存在 'Access-Control-Allow-Origin' 标头”的错误消息。

为了克服这个问题,您应该自己处理控制器中的任何异常并返回适当的错误结果,或者在之前编写中间件或用您自己的异常处理逻辑替换默认的异常中间件。

还有一个关于此行为的开放 GitHub 问题:https://github.com/aspnet/Home/issues/2378。

【讨论】:

谢谢,我明白了。但是“System.Net.Http.WinHttpException:操作超时”没有意义。我将超时时间提高到 10 分钟,然后在 30 秒内得到这些异常。也许原因是 Kestrel 无法同时处理 30-50 个请求。但我真的不相信。我忘了提到服务器是 dockerized。可能 docker 处理不了这么多的连接?【参考方案2】:

好吧,伙计们,

感谢您让我进入正确的方向。我想我找到了解决方法/修复。我必须在网关中设置以下属性:

ServicePointManager.DefaultConnectionLimit = int.MaxValue;

【讨论】:

【参考方案3】:

我也遇到了这个问题,.NET Core 2.0 不会在非 200 或非 300 响应上返回 http 状态代码。我通过创建中间件来修复它,使其位于要发送回客户端的响应的创建中。

您可以在此处查看所有步骤: https://medium.com/@arieldiaz92/net-core-2-0-fix-that-http-status-0-error-by-sending-cors-headers-on-failures-12fe3d245107

【讨论】:

以上是关于HTTP 状态码 500,.net core CORS 和 HttpClient 错误的主要内容,如果未能解决你的问题,请参考以下文章

.Net Core007Http请求

.Net Core007Http请求

http状态码汇总

HTTP 错误 500.0 - Dot net core 3.1 中的 ASP.NET Core IIS 托管失败(进程中)

验证 HTTP 200 和 500 状态码的 Alamofire 响应

在身份验证失败时返回自定义状态码 .Net Core