c# - 预检失败时如何通过属性而不是通过 Application_BeginRequest 启用 CORS

标签 c# asp.net cors asp.net-web-api2

一个多小时以来,我一直遇到 CORS 配置问题,但我找不到可以帮助我理解这种情况的问题。

我在一个暂存域上触发了一个 XHR,它带有一个返回 400 的预检 OPTIONS 请求,并且没有发送 POST,因为允许它的 CORS header 不存在。

我的 WebApiConfig.cs 中有 config.EnableCors(); 并且正在使用 NuGetMicrosoft ASP.NET Web API 2.2 跨源支持(Microsoft.AspNet.WebApi.Cors v5.23)

然后我设置了一个默认值而不是使用空的构造函数,看到this问题所以 WebApiConfig 行是:

var defaultCors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(defaultCors);

我不介意这个,但我宁愿根本不在这里设置任何东西。无论如何,这是行不通的。

OPTIONS 请求由 Global.asax.cs 处理但不写入 header 时,错误看起来像这样:

OPTIONS http://staging.example.com:8044/Controller/Action
XMLHttpRequest cannot load http://staging.example.com:8044/Controller/Action. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://staging.example.co.uk:8044' is therefore not allowed access.

当请求未在 Global.asax.cs 中处理时,错误看起来像这样:

OPTIONS http://staging.example.com:8044
XMLHttpRequest cannot load http://staging.example.com:8044/Controller/Action. Invalid HTTP status code 400

我已经能够通过在 Global.asax.cs 中使用此解决方案来访问 API 跨域:

protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
        {
            //These headers are handling the "pre-flight" OPTIONS call sent by the browser
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://staging.example.com:8044");
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Accepts, Content-Type, Origin, X-My-Header");
            HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "60");
            HttpContext.Current.Response.End();
        }
    }
}

我真正想做的是:

[EnableCors("http://www.example.com", "*", "get,post")]
public sealed class ControllerController : ApiController
{
    [EnableCors("http://staging.example.com:8044,http://www.example.com", "*", "post")]
    [HttpPost]
    public async Task<HttpResponseMessage> Action([FromBody] ModelledInput input)
    {
        ...
    }
}

我不明白为什么 CORS 属性不处理预检请求,但我明白为什么 BeginRequest 是。我希望在 Controller 或操作级别而不是全局管理 CORS 控件。我认为它可能是 HttpPost 属性,但删除它不起作用。

我对我做错了什么或者请求可能被更高层过滤或处理的建议持开放态度 - 我不确定去哪里寻找解决这个问题但我不乐意在全局范围内处理 CORS。

如果有任何帮助,我将不胜感激!

最佳答案

protected void Application_BeginRequest()
{

    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
        //These headers are handling the "pre-flight" OPTIONS call sent by the browser
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://staging.example.com:8044");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Accepts, Content-Type, Origin, X-My-Header");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "60");
        HttpContext.Current.Response.End();
    }

}

上面提到的代码对我有用

关于c# - 预检失败时如何通过属性而不是通过 Application_BeginRequest 启用 CORS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31459416/

相关文章:

javascript - Nancy + .NET Core 启用 CORS 不起作用

tomcat - 发布请求的 Elastic Beanstalk CORS 配置

c# - DataGridTemplateColumn 中的复选框出现问题

c# - c# 动态 ExpandoObjects 名称中的句点?

c# - Base Base Constructor C# 初始化

c# - Entity Framework 中的一个事务中的多个数据库

c# - IoC比较

c# - .Net Web 服务器之间的除法舍入/小数差异

C# ASP.NET MVC : Single-Line If Clause in View?

amazon-web-services - 如何为 AWS API Gateway 资源启用 CORS