MVC web api:请求的资源上没有"Access-Control-Allow-Origin"标头

Noa*_*ani 114 c# asp.net-mvc cors asp.net-web-api angularjs

我尝试了本文中所写的所有内容:http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api,但没有任何作用.我正在尝试从webAPI2(MVC5)获取数据以使用angularJS在另一个域中使用.

我的控制器看起来像这样:

namespace tapuzWebAPI.Controllers
{
    [EnableCors(origins: "http://local.tapuz.co.il", headers: "*", methods: "*", SupportsCredentials = true)]
    [RoutePrefix("api/homepage")]
    public class HomePageController : ApiController
    {
        [HttpGet]
        [Route("GetMainItems")]
        //[ResponseType(typeof(Product))]
        public List<usp_MobileSelectTopSecondaryItemsByCategoryResult> GetMainItems()
        {


            HomePageDALcs dal = new HomePageDALcs();
            //Three product added to display the data

            //HomePagePromotedItems.Value.Add(new HomePagePromotedItem.Value.FirstOrDefault((p) => p.ID == id));


            List<usp_MobileSelectTopSecondaryItemsByCategoryResult> items = dal.MobileSelectTopSecondaryItemsByCategory(3, 5);
            return items;

        }      
    }
}
Run Code Online (Sandbox Code Playgroud)

Mih*_*scu 277

您需要在Web Api中启用CORS.全局启用CORS的更简单和首选方法是将以下内容添加到web.config中

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="*" />
      <add name="Access-Control-Allow-Headers" value="Content-Type" />
      <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    </customHeaders>
  </httpProtocol>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)

请注意,方法都是单独指定的,而不是使用*.这是因为使用时发生了错误*.

您也可以通过代码启用CORS.

更新需要
以下NuGet包:Microsoft.AspNet.WebApi.Cors.

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

        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以[EnableCors]像这样使用Actions或Controllers上的属性

[EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")]
Run Code Online (Sandbox Code Playgroud)

或者您可以在全球注册

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

        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

您还需要办理预检Options 请求HTTP OPTIONS请求.

Web API需要响应Options请求以确认它确实配置为支持CORS.

要处理这个问题,您需要做的就是发送一个空响应.您可以在您的操作中执行此操作,也可以像以下一样全局执行此操作:

# Global.asax.cs
protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.Flush();
    }
}
Run Code Online (Sandbox Code Playgroud)

添加了此额外检查以确保不会被利用的旧APIs的设计为仅接受GETPOST请求.想象一下,当这个动词不存在时,DELETEAPI设计者发送请求.结果是不可预测的,结果可能是危险的.

  • 你的回答对我有帮助.我曾尝试使用代码库解决方案.在我阅读你的答案之前,我没有尝试使用web.config选项.这是唯一有效的.知道为什么吗?我正在使用带有OData的Web API 2.不管怎么说,还是要谢谢你!:) (3认同)
  • 我已经回答了您所有的问题,并且有两个问题:应该在哪里调用Application_BeginRequest()?其次,在相同的方法中,.Contains(“ Origin”)并没有真正对我进行编译,该方法来自String.Contains还是Linq.Contains? (2认同)
  • 记住一个不同的端口#构成一个不同的域,这可能是一个陷阱.foo.com _is的域名不同于foo.com:8080 (2认同)
  • 你救了我的命 ;) (2认同)

Hoc*_*eyJ 24

@ Mihai-Andrei Dinculescu的回答是正确的,但是为了搜索者的利益,还有一个微妙的点可以导致这个错误.

在URL的末尾添加"/"将阻止EnableCors在所有实例中工作(例如,从主页).

即这不起作用

var cors = new EnableCorsAttribute("http://testing.azurewebsites.net/", "*", "*");
config.EnableCors(cors);
Run Code Online (Sandbox Code Playgroud)

但这会奏效:

var cors = new EnableCorsAttribute("http://testing.azurewebsites.net", "*", "*");
config.EnableCors(cors);
Run Code Online (Sandbox Code Playgroud)

如果使用EnableCors属性,效果是相同的.


Alb*_*tSY 21

我按照Mihai-Andrei Dinculescu指出的所有步骤进行了操作.
但对我来说,我需要1层以上的步骤,因为HTTP选项是由下面的一行在web.config中禁用.

<remove name="OPTIONSVerbHandler" />

我刚从Web.Config中删除它(只是在下面评论),而Cors就像一个魅力

<handlers>
  <!-- remove name="OPTIONSVerbHandler" / -->
</handlers>
Run Code Online (Sandbox Code Playgroud)


Bim*_*Das 9

这可能是因为安装了Cors nuget包.

如果您在从nuget安装和启用cors后遇到问题,那么您可以尝试重新安装web Api.

从包管理器中运行 Update-Package Microsoft.AspNet.WebApi -reinstall


And*_*rei 6

试试这个,确保你正确配置了CORS:

[EnableCors(origins: "*", headers: "*", methods: "*")]
Run Code Online (Sandbox Code Playgroud)

还是行不通?检查HTTP标头的存在.

  • 最佳答案,因为我不想为整个站点启用 CORS,而只是为某些端点启用 CORS。为此还需要`config.EnableCors()`。 (2认同)

小智 5

我知道我来得很晚。但是,对于正在搜索的任何人,我想我会发布最终对我有用的内容。我并不是说这是最好的解决方案——只是说它有效。

我们的 WebApi 服务使用 config.EnableCors(corsAttribute) 方法。然而,即便如此,它仍然会在飞行前请求上失败。@Mihai-Andrei Dinculescu 的回答为我提供了线索。首先,我添加了他的 Application_BeginRequest() 代码来刷新选项请求。那仍然对我不起作用。问题是 WebAPI 仍然没有向 OPTIONS 请求添加任何预期的标头。单独冲洗它没有用 - 但它给了我一个想法。我添加了自定义标头,否则这些标头将通过 web.config 添加到 OPTIONS 请求的响应中。这是我的代码:

protected void Application_BeginRequest()
{
  if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
  {
    Response.Headers.Add("Access-Control-Allow-Origin", "https://localhost:44343");
    Response.Headers.Add("Access-Control-Allow-Headers",
      "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
    Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    Response.Flush();
  }
}
Run Code Online (Sandbox Code Playgroud)

显然,这仅适用于 OPTIONS 请求。所有其他动词都由 CORS 配置处理。如果有更好的方法来解决这个问题,我会全力以赴。对我来说这感觉像是作弊,我更喜欢自动添加标题,但这最终奏效并让我继续前进。