简体   繁体   English

ASP.NET Core CORS 请求被阻止; 为什么我的 API 没有应用正确的标头?

[英]ASP.NET Core CORS request blocked; why doesn't my API apply the right headers?

Trying to set up CORS with authentication.尝试使用身份验证设置 CORS。 I have a Web API site up at http://localhost:61000 and a consuming web application up at http://localhost:62000 .我在http://localhost:61000 上有一个 Web API 站点,在http://localhost:62000 上有一个消费 Web 应用程序。 In the Web API Startup.cs, I have:在 Web API Startup.cs 中,我有:

 public void ConfigureServices(IServiceCollection services)
 {
        services.AddCors(o => o.AddPolicy("MyPolicy", corsBuilder =>
        {
            corsBuilder.WithOrigins("http://localhost:62000")
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials();
        }));
        IMvcBuilder builder = services.AddMvc();
        // ...
}

// ...

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
        app.UseCors("MyPolicy");
        app.UseDeveloperExceptionPage();
        app.UseDefaultFiles();
        app.UseStaticFiles();
        app.UseMvc();
}

All the doucmentation seems to indicate that should be all I need.所有的文件似乎都表明这应该是我所需要的。 In my app's Javascript, I call:在我的应用程序的 Javascript 中,我调用:

    $.ajax({
        type: 'POST',
        url: "http://localhost:61000/config/api/v1/MyStuff",
        data: matchForm.serialize(),
        crossDomain: true,
        xhrFields: { withCredentials: true },
        success: function (data) {
            alert(data);
        }
    });

And I get in Chrome: Failed to load http://localhost:61000/config/api/v1/MyStuff: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:62000' is therefore not allowed access.我进入 Chrome: Failed to load http://localhost:61000/config/api/v1/MyStuff: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:62000' is therefore not allowed access. Failed to load http://localhost:61000/config/api/v1/MyStuff: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:62000' is therefore not allowed access.

...and in Firefox: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:61000/config/api/v1/MyStuff. (Reason: CORS header 'Access-Control-Allow-Origin' missing). ...在 Firefox 中: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:61000/config/api/v1/MyStuff. (Reason: CORS header 'Access-Control-Allow-Origin' missing). Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:61000/config/api/v1/MyStuff. (Reason: CORS header 'Access-Control-Allow-Origin' missing).

What am I missing?我错过了什么? This should be all I need to enable CORS, I thought, but clearly there is something else missing.我想,这应该是启用 CORS 所需的全部内容,但显然还缺少其他东西。

For ASP.NET Core 2.1 and earlier:对于 ASP.NET Core 2.1 及更早版本:

It seems there was an error in my code, but I got the obscure error noted instead of getting an ASP.NET-generated error page.我的代码中似乎有一个错误,但我得到了一个模糊的错误,而不是得到一个 ASP.NET 生成的错误页面。 It turns out that the CORS headers are indeed properly applied at first, but then they are stripped off any ASP.NET middleware-generated errors .事实证明,CORS 标头一开始确实被正确应用,但随后它们被剥离了任何 ASP.NET 中间件生成的错误 See also https://github.com/aspnet/Home/issues/2378 .另请参阅https://github.com/aspnet/Home/issues/2378

I used that link to figure out this class我用那个链接来找出这门课

using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace MySite.Web.Middleware
{
    /// <summary>
    /// Reinstates CORS headers whenever an error occurs.
    /// </summary>
    /// <remarks>ASP.NET strips off CORS on errors; this overcomes this issue,
    ///  explained and worked around at https://github.com/aspnet/Home/issues/2378 </remarks>
    public class MaintainCorsHeadersMiddleware
    {
        public MaintainCorsHeadersMiddleware(RequestDelegate next)
        {
            _next = next;
        }
        private readonly RequestDelegate _next;

        public async Task Invoke(HttpContext httpContext)
        {
            // Find and hold onto any CORS related headers ...
            var corsHeaders = new HeaderDictionary();
            foreach (var pair in httpContext.Response.Headers)
            {
                if (!pair.Key.ToLower().StartsWith("access-control-")) { continue; } // Not CORS related
                corsHeaders[pair.Key] = pair.Value;
            }

            // Bind to the OnStarting event so that we can make sure these CORS headers are still included going to the client
            httpContext.Response.OnStarting(o => {
                var ctx = (HttpContext)o;
                var headers = ctx.Response.Headers;
                // Ensure all CORS headers remain or else add them back in ...
                foreach (var pair in corsHeaders)
                {
                    if (headers.ContainsKey(pair.Key)) { continue; } // Still there!
                    headers.Add(pair.Key, pair.Value);
                }
                return Task.CompletedTask;
            }, httpContext);

            // Call the pipeline ...
            await _next(httpContext);
        }
    }
}

And then I added it to my site configuration in Startup.cs:然后我将它添加到 Startup.cs 中的站点配置中:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseCors(...);
        app.UseMiddleware<MaintainCorsHeadersMiddleware>();

        ...
        app.UseMvc();
    }

ASP.NET Core 2.2.0 Answer ASP.NET Core 2.2.0 答案

This issue is now fixed .此问题现已修复 CORS headers are now returned even when exceptions are thrown and a 500 response is returned.即使抛出异常并返回 500 响应,现在也会返回 CORS 标头。

ASP.NET Core <= 2.1.0 Answer ASP.NET Core <= 2.1.0 答案

CORS Headers were stripped from the response when an exception is thrown and a 500 response is returned.当抛出异常并返回 500 响应时,CORS 标头会从响应中剥离。

I was having this same issue on a Web API project using OWIN middleware, where a wrong package version was causing errors on the API side (hidden on the client side because CORS headers were stripped on the response, which obscured the original error).我在使用 OWIN 中间件的 Web API 项目上遇到了同样的问题,其中错误的包版本导致 API 端出现错误(隐藏在客户端,因为响应中的 CORS 标头被剥离,这掩盖了原始错误)。 I implemented a similar solution to yours, sharing here because I could not find any similar example using OWIN on the web:我实现了与您类似的解决方案,在这里分享,因为我在网上找不到任何使用 OWIN 的类似示例:

using System;
using System.Linq;
using System.Threading.Tasks;
using Owin;
using Microsoft.Owin;
using Microsoft.Owin.Cors;

namespace App_Server
{
    using AppFunc = Func<IDictionary<string, object>, Task>;
    partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(CorsOptions.AllowAll);
            app.Use(new Func<AppFunc, AppFunc>(RetainHeaders));
            ....
            (other startup tasks)
        }

        private AppFunc RetainHeaders(AppFunc next)
        {
            AppFunc appFunc = async (IDictionary<string, object> context) =>
            {
                IOwinContext httpContext = new OwinContext(context);
                var corsHeaders = new HeaderDictionary(new Dictionary<string, string[]>());

                foreach (var pair in httpContext.Response.Headers)
                {
                    if (!pair.Key.ToLower().StartsWith("access-control-")) { continue; } //not a CORS header
                    corsHeaders[pair.Key] = pair.Value.First();
                }

                httpContext.Response.OnSendingHeaders(o =>
                {
                    var localcontext = new OwinContext((IDictionary<string, object>)o);
                    var headers = localcontext.Response.Headers;
                    //make sure headers are present, and if not, add them back
                    foreach (var pair in corsHeaders)
                    {
                        if (headers.ContainsKey(pair.Key)) { continue; }
                        headers.Add(pair.Key, pair.Value);
                    }
                }, context);

                await next.Invoke(context);
            };
            return appFunc;
        }
}

This was a quite a process to work out given how poorly documented the OWIN packages are for .Net, so I hope it helps someone else who comes across it looking for a solution.鉴于 OWIN 包对于 .Net 的文档记录很差,这是一个相当大的过程,所以我希望它可以帮助遇到它的其他人寻找解决方案。

In my case the CORS headers were lost because I was making an "application/json" content type request, and in CORS this type of request send first an OPTIONS method, after that, the regular POST is requested.在我的情况下,CORS 标头丢失了,因为我正在发出“应用程序/json”内容类型请求,而在 CORS 中,这种类型的请求首先发送一个 OPTIONS 方法,然后请求常规 POST。 But the OPTIONS was been managed by a Middleware code in my .Net Core pipeline with something like this:但是 OPTIONS 是由我的 .Net Core 管道中的中间件代码管理的,如下所示:

        if (context.Request.Method == "OPTIONS")
        {
            context.Response.StatusCode = (int)HttpStatusCode.OK;
            await context.Response.WriteAsync(string.Empty);
        } 

Once I remove the middleware those requests were flawless attended.一旦我删除了中间件,这些请求就会得到完美的处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么ASP.NET Core Web API中没有这种死锁? - Why doesn't this deadlock in ASP.NET Core Web API? Angular 6 Asp.Net(非核心)Web Api CORS 请求失败 - Angular 6 Asp.Net (not Core) Web Api CORS request fails 似乎无法验证对我的 ASP.NET 核心 API 的请求 - Can't seem to authenticate a request to my ASP.NET Core API Call to my rest service from Angular app hosted in Asp.net core web server blocked by CORS policy - Call to my rest service from Angular app hosted in Asp.net core web server blocked by CORS policy API 不起作用,使用 Docker 和 ASP.NET CORE - API doesn't work, using Docker and ASP.NET CORE 为什么Test Explorer没有看到我对ASP.NET Core MVC的NUnit测试? - Why Test Explorer doesn't see my NUnit tests for ASP.NET Core MVC? 跨源请求在asp.net核心信号R中被阻止? - Cross origin request blocked in asp.net core signalR? 使用 Windows 身份验证的 Asp.net 核心 Web api - Cors 请求未经授权 - Asp.net core web api using windows authentication - Cors request unauthorised AddSingleton 在我的 ASP.NET 核心项目中不起作用 - AddSingleton doesn't work in my ASP.NET Core project 为什么 asp.net 内核 model 绑定不起作用? - Why doesn't asp.net core model binding work?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM