MVC web api:没有“Access-Control-Allow-Origin”标题出现在请求的资源上

我尝试了所有写在这篇文章中的东西: 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; } } } 

您需要在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> 

请注意,这些方法都是单独指定的,而不是使用* 。 这是因为使用*时出现错误。

您也可以通过代码启用CORS

更新
以下NuGet包是必需的: Microsoft.AspNet.WebApi.Cors

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

然后你可以像这样在Actions或者Controllers上使用[EnableCors]属性

 [EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")] 

或者你可以在全球注册

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

您还需要使用HTTP OPTIONS请求处理预检Options请求。

Web API需要响应Options请求以确认它确实被configuration为支持CORS

为了解决这个问题,你只需要发送一个空的响应 。 你可以在你的行动中做到这一点,或者你可以这样做,像这样:

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

这个额外的检查被添加来确保被devise为仅接受GETPOST请求的旧APIs不被利用。 想象一下,当这个动词不存在时,向devise的API发送一个DELETE请求。 结果是不可预测的 ,结果可能是危险的

@ Mihai-Andrei Dinculescu的答案是正确的,但为了search者的利益,还有一个微妙的一点可能会导致这个错误。

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

即这是行不通的

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

但是这将工作:

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

如果使用EnableCors属性,效果是一样的。

这可能是因为安装了Cors nuget软件包。

如果从nuget安装并启用cors后面临问题,那么您可以尝试重新安装web Api。

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

要使任何CORS协议工作,您需要在每个端点(或使用此方法的全局filter)上都有一个OPTIONS方法,它将返回这些标头:

 Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT, DELETE Access-Control-Allow-Headers: content-type 

原因是浏览器将首先发送一个OPTIONS请求来“testing”你的服务器并查看授权

我遵循了Mihai-Andrei Dinculescu指出的所有步骤。
但在我的情况下,我需要多一个步骤,因为HTTP OPTIONS被禁用在Web.Config由下面的行。

<remove name="OPTIONSVerbHandler" />

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

 <handlers> <!-- remove name="OPTIONSVerbHandler" / --> </handlers> 

试试这个,确保你正确地configuration了CORS:

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

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

@ Mihai-Andrei Dinculescu的答案为我工作,例如:

  • 在web.config的<system.webServer>部分添加一个<httpProtocol>
  • 通过global.asax提到的Application_BeginRequest()返回OPTIONS请求的空响应

除了他对Request.Headers.AllKeys.Contains("Origin")没有为我工作,因为请求包含origing ,所以用小写。 我想我的浏览器(Chrome)发送这样的CORS请求。

我通过使用Contains检查的不区分大小写的变体来解决这个问题: if (culture.CompareInfo.IndexOf(string.Join(",", Request.Headers.AllKeys), "Origin", CompareOptions.IgnoreCase) >= 0) {