MVC Web API:所请求的资源上不存在“ Access-Control-Allow-Origin”标头


128

我尝试了本文中写的所有内容: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;

        }      
    }
}

1
还要分享您请求cors的角度代码
harishr 2014年

2
他的角度代码可能没有问题,因为大多数CORS问题只是由于服务器配置
sam

我有相同的设置方式,我注意到当我请求对API执行不存在的操作时,WebApi返回404时,CORS标头丢失,浏览器将抱怨。因此,也许就这么简单。
罗宾·范德·纳纳普

Answers:


295

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

        // ...
    }
}

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

[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);

        // ...
    }
}

您还需要办理预检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();
    }
}

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


3
你的回答帮助了我。我已经尝试了所有使用代码库解决方案的方法。在阅读您的答案之前,我没有尝试过web.config选项。这是唯一可行的方法。知道为什么吗?我正在将Web API 2与OData一起使用。不管怎么说,还是要谢谢你!:)
Felipe Correa 2015年

1
供将来参考,您需要的NuGet软件包是“ Microsoft.AspNet.WebApi.Cors”。
BrainSlugs83 '16

2
我已经回答了您所有的问题,并且有两个问题:应该在哪里调用Application_BeginRequest()?其次,在相同的方法中,.Contains(“ Origin”)并没有真正对我进行编译,该方法来自String.Contains还是Linq.Contains?
meJustAndrew

2
请记住,不同的端口#构成不同的域,这可能是一个陷阱。foo.com foo.com 是不同的域: 8080
RyBolt

1
您救了我的命;)
PawełGroński17年

26

@ Mihai-Andrei Dinculescu的答案是正确的,但是对于搜索者来说,还有一个细微的问题可以导致此错误。

在网址末尾添加“ /”将阻止EnableCors在所有情况下(例如,从首页开始)工作。

即这行不通

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

但这可以工作:

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

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


谢谢!!这很有帮助。
Ankit Sahrawat

23

我遵循了Mihai-Andrei Dinculescu指示的上述所有步骤。
但就我而言,我需要再执行1步,因为在Web.Config中通过以下行禁用了HTTP OPTIONS。

<remove name="OPTIONSVerbHandler" />

我刚刚从Web.Config中删除了它(只需像下面这样注释),Cors就像一个吊饰

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

9

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

如果您在从nuget安装和启用cors后遇到问题,则可以尝试重新安装Web Api。

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


对我来说就是这样。我安装了System.Web.Http.Cors,然后将其卸载,这使WebApi处于错误的(新升级的)版本5.2.2和5.2.3之间
TaeKwonJ​​oe

7

尝试执行此操作,以确保正确配置了CORS:

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

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


检查它是否正常工作,最好也删除supportCredentials,它在某些情况下确实禁用了cors
harishr 2014年

最佳答案,因为我不想为整个站点(仅某些端点)启用CORS。config.EnableCors()也是需要的。
卡萨巴·托斯

4

为了使任何CORS协议都能正常工作,您需要在每个端点(或带有此方法的全局过滤器)上都有一个OPTIONS方法,该方法将返回这些标头:

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

原因是浏览器将首先发送一个OPTIONS请求以“测试”您的服务器并查看授权


2

我接下下一个关于cors的案例。也许对某人有用。如果将功能“ WebDav重定向器”添加到服务器,则PUT和DELETE请求将失败。

因此,您将需要从IIS服务器中删除“ WebDAVModule”:

  • “在IIS模块配置中,循环WebDAVModule,如果您的Web服务器拥有它,则将其删除”。

或添加到您的配置中:

<system.webServer>
<modules>
  <remove name="WebDAVModule"/>
</modules>
<handlers>
  <remove name="WebDAV" />
  ...
</handlers>


2

我知道我来晚了。但是,对于正在搜索的任何人,我都认为我会发布FINALLY对我有用的东西。我并不是说这是最好的解决方案-只是它有效。

我们的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();
  }
}

显然,这仅适用于OPTIONS请求。所有其他动词均由CORS配置处理。如果有更好的方法可以解决,我全神贯注。这对我来说似乎是一种欺骗,我希望自动添加标头,但这是最终可行的方法,让我继续前进。


1

@ Mihai-Andrei Dinculescu的回答对我有用,例如:

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

除非他的支票对Request.Headers.AllKeys.Contains("Origin")我不起作用,因为该请求包含origing,所以使用小写字母。我认为我的浏览器(Chrome)会像这样将其发送给CORS请求。

我通过使用他的支票不区分大小写的变体来更一般地解决了这个问题Contains if (culture.CompareInfo.IndexOf(string.Join(",", Request.Headers.AllKeys), "Origin", CompareOptions.IgnoreCase) >= 0) {


0

如果您的web.config中有security \ requestFiltering节点,如下所示:

<security>
  <requestFiltering>
    <verbs allowUnlisted="false">
      <add verb="GET" allowed="true" />
      <add verb="POST" allowed="true" />
      <add verb="PUT" allowed="true" />
      <add verb="DELETE" allowed="true" />
      <add verb="DEBUG" allowed="true" />          
    </verbs>
  </requestFiltering>

确保您也添加此

<add verb="OPTIONS" allowed="true" />

0

我尝试了所有可以在网上找到的内容,包括此答案中给出的方法。在几乎试图解决一整天的问题之后,我发现了对我有用的解决方案,就像是一种魅力。

在文件夹App_Start中的WebApiConfig文件中,注释所有代码行并添加以下代码:

`public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.EnableCors();
        var enableCorsAttribute = new EnableCorsAttribute("*",
                                           "Origin, Content-Type, Accept",
                                           "GET, PUT, POST, DELETE, OPTIONS");
        config.EnableCors(enableCorsAttribute);
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            //routeTemplate: "api/{controller}/{id}",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        config.Formatters.Add(new BrowserJsonFormatter());
    }

    public class BrowserJsonFormatter : JsonMediaTypeFormatter
    {
        public BrowserJsonFormatter()
        {
            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            this.SerializerSettings.Formatting = Formatting.Indented;
        }

        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            base.SetDefaultContentHeaders(type, headers, mediaType);
            headers.ContentType = new MediaTypeHeaderValue("application/json");
        }
    }`

0

我知道人们一开始可能会发现这很明显,但是请真正考虑一下。如果您做错了事,通常会发生这种情况。

例如,我遇到了这个问题,因为我没有将主机条目添加到我的主机文件中。真正的问题是DNS解析。或者我只是把基本URL弄错了。

如果身份令牌来自一台服务器,有时会出现此错误,但是我试图在另一台服务器上使用它。

如果资源有误,有时会出现此错误。

如果您将CORS中间件放在链中的时间太晚,则可能会收到此消息。


0

避免在提供程序和Controller Header属性等中启用CORS,WebApiCOnfig.cs,GrantResourceOwnerCredentials方法等多个位置。以下是也会导致访问控制允许来源的列表

  1. 与您使用的DB交互时有麻烦的Web。
  2. AWS Cloud如果Web API的VPC和数据库不同。

下面的代码足以解决访问控制允许的来源。//确保app.UseCors应该位于配置的代码行的顶部。

   public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            //All other configurations
        }
    }

这放慢了我的问题。


0

当您尝试从其他域或其他端口访问时,会发生此问题。

如果您使用的是Visual Studio,请转到工具> NuGet程序包管理器>程序包管理器控制台。在那里,您必须安装NuGet软件包Microsoft.AspNet.WebApi.Cors

Install-Package Microsoft.AspNet.WebApi.Cors

然后,在PROJECT> App_Start> WebApiConfig中,启用CORS

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        
        //Enable CORS. Note that the domain doesn't have / in the end.
        config.EnableCors(new EnableCorsAttribute("https://tiagoperes.eu",headers:"*",methods:"*"));

        ....

    }
}

成功安装后,构建解决方案就足够了

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.