EnableCors属性未将Access-Control-Allow-Origin添加到API响应

时间:2020-07-30 19:12:01

标签: c# asp.net-mvc api access-control-allow-origin

问题:

由于某些原因,启用CORS时,Access-Control-Allow-Origin标头不包含在响应中。

错误:

通过以下网址访问“ https://.../api/endpoints/some-path”处的XMLHttpRequest 原点“ https://some.site.com”已被CORS政策阻止: 对预检请求的响应未通过访问控制检查:否 请求中出现“ Access-Control-Allow-Origin”标头 资源。

配置(.NET MVC 5)

web.config 标头:

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Credentials" value="true"/>
      <add name="Access-Control-Allow-Headers" value="Content-Type" />
      <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, OPTIONS" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

Web API配置:

config.EnableCors();

API端点:

[RoutePrefix("api/endpoints")]
[EnableCors(origins: "https://some.site.com", headers: "*", methods: "*")]
public class MyApiController : ApiController
{
    [HttpPost]
    [Route("some-path")]
    [EnableCors(origins: "https://some.site.com", headers: "*", methods: "*")]
    public ResponseModel GetSomeResponse(DataModel model) { ... }
}

global.asax.cs

protected void Application_BeginRequest(object sender, EventArgs e)
{
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
        HttpContext.Current.Response.Flush();
}

我成功获取应用程序以返回该标头的唯一方法是将其作为自定义标头明确包含在 web.config 中:

<add name="Access-Control-Allow-Origin" value="https://some.site.com" />

7 个答案:

答案 0 :(得分:0)

使用HttpOptions标头和相同的路由名称添加相同的方法。浏览器会将预检请求发送到您的控制器。这意味着将触发Options方法来访问服务器的标头信息。

[HttpOptions]
[Route("some-path")]
[EnableCors(origins: "https://some.site.com", headers: "*", methods: "*")]
public ResponseModel GetSomeResponse(DataModel model) { ... }

答案 1 :(得分:0)

来自:https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api

确认Access-Control-Request-Method和Access-Control-Request-Headers标头与请求一起发送,并且OPTIONS标头通过IIS到达应用程序。

要配置IIS以允许ASP.NET应用程序接收和处理OPTION请求,请在部分的应用程序的web.config文件中添加以下配置:

<system.webServer>
  <handlers>
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="OPTIONSVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  </handlers>
</system.webServer>

删除OPTIONSVerbHandler可以防止IIS处理OPTIONS请求。替换ExtensionlessUrlHandler-Integrated-4.0允许OPTIONS请求到达应用程序,因为默认模块注册仅允许使用无扩展URL的GET,HEAD,POST和DEBUG请求。

答案 2 :(得分:0)

这对我有用。处理飞行前请求和更正 Web.config

<system.webServer>   
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>

Global.asax.cs

protected void Application_BeginRequest(object sender, EventArgs e)
        {
            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", "*");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "*"); // For All HttpVerb
                //HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
                //HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");
                //HttpContext.Current.Response.AddHeader("Access-Control-Allow‌​-Credentials", "true");
                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "600");//1728000
                HttpContext.Current.Response.StatusCode = 204;

                HttpContext.Current.Response.End();
            }
        }

WebApiConfig.cs

public static void Register(HttpConfiguration config)
{
    config.EnableCors();
    ....
}

在控制器中添加属性

[EnableCors(origins: "*", headers: "*", methods: "*")]

答案 3 :(得分:0)

如果可能,请始终尝试使代码简单清除

实际上,无需更改 web.config 控制器 global.asax.cs 。因此,请清洁它们并只需在 Startup.cs 文件的Configure方法内使用以下配置

app.UseExceptionHandler(builder =>
{
    builder.Run(
    async context =>
    {
        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        context.Response.Headers.Add("Access-Control-Allow-Origin", "*");

        var error = context.Features.Get<IExceptionHandlerFeature>();
        if (error != null)
        {
            context.Response.AddApplicationError(error.Error.Message);
            await context.Response.WriteAsync(error.Error.Message).ConfigureAwait(false);
        }
    });
});

其中ResponseExtensions被定义为扩展名,其中包含以下详细信息:

public static class ResponseExtensions
{
    public static void AddApplicationError(this HttpResponse response, string message)
    {
        response.Headers.Add("Application-Error", message);
        // CORS
        response.Headers.Add("access-control-expose-headers", "Application-Error");
    }
}

这在我完全基于API的Asp.net项目中正常运行。

答案 4 :(得分:-1)

为所有控制器全局设置CORS。在WebApiConfig类中,创建EnableCorsAttribute的实例,并在EnableCors方法中将其用作:

var cors = new EnableCorsAttribute("https://some.site.com", "*", "*");
config.EnableCors(cors);

答案 5 :(得分:-1)

全局启用CORS 所描述的方法还可以用于在整个API上启用CORS,而无需按照下面WebApiConfig中的注释每个控制器

public static void Register(HttpConfiguration config)
{
    var corsAttr = new EnableCorsAttribute("http://example.com", "*", "*");
    config.EnableCors(corsAttr);
}

答案 6 :(得分:-1)

我遵循了Shaun在下面的帖子中分享的相同步骤,我们可以在方法级别启用CORS。这对我来说可以。 您能不能尝试一下?

Asp.Net WebApi2 Enable CORS not working with AspNet.WebApi.Cors 5.2.3

相关问题