在.NET Core Web API上为CORS启用OPTIONS标头

Nie*_*nch 20 .net-core asp.net-core asp.net-core-webapi

我没有在Stackoverflow上找到解决方案后解决了这个问题,所以我在这里分享我的问题和答案中的解决方案.

在使用AddCors的.NET Core Web Api应用程序中启用跨域策略后,它仍无法在浏览器中运行.这是因为浏览器(包括Chrome和Firefox)将首先发送OPTIONS请求,而我的应用程序只响应204 No Content.

Nie*_*nch 24

在项目中添加一个中间件类来处理OPTIONS动词.

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

namespace Web.Middlewares
{
    public class OptionsMiddleware
    {
        private readonly RequestDelegate _next;

        public OptionsMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public Task Invoke(HttpContext context)
        {
            return BeginInvoke(context);
        }

        private Task BeginInvoke(HttpContext context)
        {
            if (context.Request.Method == "OPTIONS")
            {
                context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { (string)context.Request.Headers["Origin"] });
                context.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "Origin, X-Requested-With, Content-Type, Accept" });
                context.Response.Headers.Add("Access-Control-Allow-Methods", new[] { "GET, POST, PUT, DELETE, OPTIONS" });
                context.Response.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" });
                context.Response.StatusCode = 200;
                return context.Response.WriteAsync("OK");
            }

            return _next.Invoke(context);
        }
    }

    public static class OptionsMiddlewareExtensions
    {
        public static IApplicationBuilder UseOptions(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<OptionsMiddleware>();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将其添加app.UseOptions();为Configure方法中Startup.cs中的第一行.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseOptions();
}
Run Code Online (Sandbox Code Playgroud)

  • +1,但有一点需要调整,不要调用_next.Invoke如果方法是选项,请求应该在调用`context.Response.WriteAsync("OK");`之后结束,所以将`Invoke`实现更改为:`if(context.Request.Method!="OPTIONS"){等待this._next.Invoke(context); }` (6认同)
  • @AmenAyach并不重要,因为在 if 语句中它返回`context.Response.WriteAsync("OK");`,所以如果方法是 OPTIONS 则永远不会到达`_next.invoke(context)` (2认同)

use*_*627 19

这对我有用:

确保:

app.UseCors(builder => {
    builder.AllowAnyOrigin();
    builder.AllowAnyMethod();
    builder.AllowAnyHeader();
});
Run Code Online (Sandbox Code Playgroud)

在以下任何一个之前发生:

app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseCookiePolicy();
Run Code Online (Sandbox Code Playgroud)

请记住,我们正在处理“管道”。cors 的东西必须是第一位的。

-gimzani

  • 谢谢,这对我有用。我想强调的是,cors 的东西必须先于任何其他 HTTP 请求管道配置方法,正如 @NielsBrinch 所说。 (2认同)

Jey*_*ara 9

我知道已经回答了。只需回答更新的信息即可。这样对别人有帮助。

现在,它已内置到ASP.NET Core框架中。

只需遵循https://docs.microsoft.com/zh-cn/aspnet/core/security/cors

并更换

    app.UseCors(builder =>
   builder.WithOrigins("http://example.com"));
Run Code Online (Sandbox Code Playgroud)

        app.UseCors(builder =>
       builder.WithOrigins("http://example.com")
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials());
Run Code Online (Sandbox Code Playgroud)

  • 它行得通吗?问题是Chrome会先发送“ OPTIONS”呼叫,并且不会获得批准,因此真正的呼叫永远不会来自Chrome浏览器。那是“ AllowAnyMethod”解决的问题吗?编辑:我现在看到的正是它们在您链接的文章中所解决的! (2认同)
  • 通过这样做,我在响应状态代码中得到“ 204 No Content” (2认同)
  • “204 No Content”是一个问题吗?似乎您应该从“OPTIONS”请求中获得的唯一信息是在标头中。不?[Mozilla 似乎同意](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS)。 (2认同)
  • 这需要进入“Startup.cs”中的“Configure()” (2认同)

Tar*_*nii 7

不需要额外的中间件。如上所述,唯一需要的是 Cors 配置中允许的 OPTIONS 方法。您可以按照此处的建议 AllowAnyMethod:https ://stackoverflow.com/a/55764660/11921910

但是只允许这样的特定内容更安全:

app.UseCors(builder => builder
.WithOrigins("https://localhost", "https://production.company.com") /* list of environments that will access this api */
.WithMethods("GET", "OPTIONS") /* assuming your endpoint only supports GET */
.WithHeaders("Origin", "Authorization") /* headers apart of safe-list ones that you use */
);
Run Code Online (Sandbox Code Playgroud)

始终允许使用某些标题:https : //developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_request_header


Sha*_*uti 7

AspNetCoreModuleV2 选项问题

.Net core 模块不知道如何处理 OPTIONS,这会导致预检 CORS 问题,因此解决方案是将 OPTIONS 动词排除在其处理之外。这是通过将 * 替换为您想要的动词(选项除外)来完成的。不用担心,OPTIONS 动词将由默认加载的 OPTIONSHandler 处理:

信息系统

解决方案:修改web.config

 <add name="aspNetCore" path="*" verb="* modules="AspNetCoreModuleV2" resourceType="Unspecified" />
Run Code Online (Sandbox Code Playgroud)

让它像这样:

<add name="aspNetCore" path="*" verb="GET,POST,PUT,DELETE" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
Run Code Online (Sandbox Code Playgroud)

IIS Express:用于 Visual Studio 调试器

我尝试修改 .vs\ProjectName\config\applicationhost.config 文件底部但没有希望。因此,在这种特定情况下,您可以使用所选的答案。