我在dotnet核心中遇到了一些关于CORS / HttpClient的问题。首先,我的应用程序结构如下:
Webapp -> Microservice-Gateway -> multiple Microservices
如果我从Webapp执行Ajax调用
$.ajax({
url: "https://[actual gateway Url]/customer/" + customerId,
type: "GET",
timeout: 60000,
crossDomain: true,
dataType: "json",
success: data => {
//...
}
});
到我收到的网关服务器有时会出现以下错误消息:
否'访问控制 - 允许 - 来源'标题出现在请求的上 资源。起源' 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调用,问题似乎更频繁出现。但这也可能只是一种感觉。
答案 0 :(得分:2)
这可能与您的CORS设置无关。发生错误时(例如,使用HttpClient
进行HTTP调用),默认的异常处理程序中间件会删除所有响应头并返回错误响应。这意味着您的策略添加的任何CORS标头都将被删除,因此您将收到有关“No'Access-Control-Allow-Origin'标头出现在请求的资源上的错误。”。
为了解决这个问题,您应该自己处理控制器中的任何异常并返回相应的错误结果,或者在使用您自己的异常处理逻辑之前编写中间件或替换默认的异常中间件。
还有一个关于此行为的公开GitHub问题:https://github.com/aspnet/Home/issues/2378。
答案 1 :(得分:0)
好的,
感谢让我走向正确的方向。我想我找到了解决方法/修复方法。我必须在我的网关中设置以下属性:
ServicePointManager.DefaultConnectionLimit = int.MaxValue;
答案 2 :(得分:0)
我也遇到了这个问题,.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