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为仅接受GET
和POST
请求的旧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) {