MVC web api: 请求的资源上没有“访问控制-允许-起源”头

我尝试了本文中编写的所有方法: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api,但都不管用。 我正在尝试使用 angularJS 从 webAPI2(MVC5)获取数据,以便在另一个域中使用。

我的控制器是这样的:

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;


}
}
}
244089 次浏览

试试这个,以确保您正确地配置了 CORS:

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

仍然不工作? 检查 HTTP 头是否存在。

为了让 CORS 协议正常工作,您需要在每个端点上都有一个 OPTION 方法(或者使用这个方法的全局过滤器) ,它将返回这些头:

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

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

您需要在 网络阿皮中启用 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>

请注意,方法都是单独指定的,而不是使用 *。这是因为在使用 *时出现了一个 bug。

还可以通过代码启用 CORS

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

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


// ...
}
}

然后您可以像下面这样在 Actions 或 Controller 上使用 [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);


// ...
}
}

您还需要处理飞行前 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();
}
}

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

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

在 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 属性,效果是相同的。

我遵循了 Mihai-Andrei Dinculescu指示的所有步骤。
但是在我的例子中,我需要 再来一杯步骤,因为 Web 中禁用了 http 选项。按下面的行进行配置。

<remove name="OPTIONSVerbHandler" />

我只是从 Web.Config 中删除了它(只需要像下面这样注释它) ,Cors 工作起来非常有效

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

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

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

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

我通过使用他的 Contains检查的 对案件不敏感变体解决了这个问题: 如果(区域性。 CompareInfo.IndexOf (字符串。连接(“ ,”,请求。头。 AllKeys) ,“起源”,CompareOptions。 IgnoreCase) > = 0){

这可能是因为安装了科尔斯金刚石软件包。

如果您在安装并启用来自 nuget 的 cors 之后遇到了这个问题,那么您可以尝试重新安装 webApi。

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

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

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

  • “在 IIS 模块配置中,循环使用 WebDAVModule,如果您的 Web 服务器有这个模块,那么删除它”。

或添加到您的配置:

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

如果您的 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" />

我已经尝试了一切我可以在网上找到的方法,包括已经给出了这个答案。 在几乎尝试了一整天解决这个问题之后,我找到了一个非常适合我的解决方案。

在文件夹 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");
}
}`

我知道我来得很晚了。然而,对于任何正在搜索的人来说,我认为我应该发表最终对我有用的东西。我并不是说这是最好的解决方案——只是说它起作用了。

我们的 WebApi 服务使用这个配置。EnableCors (corsAttribute)方法。然而,即使这样,它仍然不能满足飞行前的请求。@ Mihai-Andrei Dinculescu 的回答为我提供了线索。首先,我添加了他的 Application _ BeginRequest ()代码来刷新选项请求。这招对我还是不管用。问题是 WebAPI 仍然没有将任何预期的头添加到 OPTION 请求中。单独冲洗不起作用,但它给了我一个想法。我为 OPTION 请求的响应添加了通过 web.config 添加的自定义头文件。这是我的密码:

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

显然,这只适用于 OPTION 请求。所有其他动词由 CORS 配置处理。如果有更好的办法,我洗耳恭听。这对我来说就像是一个骗局,我更希望标题是自动添加的,但这是什么最终工作,并允许我继续前进。

我知道人们一开始可能会觉得这很明显,但是仔细想想。如果你做错了什么,这种情况经常会发生。

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

如果标识令牌来自一个服务器,有时我会得到这个错误,但我试图在另一个服务器上使用它。

如果资源错误,有时会得到这个错误。

如果您将 CORS 中间件放在链中的时间太晚,您可能会得到这个结果。

避免在多个地方启用 CORS,比如 WebApiCOnfig.cs、 GrantResourceOwnerCredentials 方法的 Provider 和 Controller Header 属性等。 下面是导致访问控制允许起源的列表

  1. 在与你使用的数据库进行交互时遇到困难。
  2. 如果 Web API 和数据库的 VPC 不同,则使用 AWS 云。

下面的代码足以修复访问控制允许原点。 //确保 app. UseCors 应该位于配置代码行的顶部。

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

这减缓了我的问题。

当您尝试从不同的域或不同的端口访问时,就会发生这个问题。

如果你正在使用 Visual Studio,那么点击 Tools > NuGet Package Manager > Package Manager Console。在那里您必须安装 NuGet 软件包 微软.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:"*"));


....


}
}

一旦安装成功,构建解决方案,应该就足够了

安装包: Microsoft.AspNet.WebApi.Cors

转到: App _ Start —— > WebApiConfig

地址:

Var cors = new EnableCorsAttribute (“ http://localhost:4200" ; ,“ “ ,””) ; EnableCors (cors) ;

注意: 如果你添加’/’作为结束的特定网址不适合我。

中创建 Web API 的用户。NET 5而不是 Web 应用程序,在 Startup.cs中你需要这样配置你的策略:

public void ConfigureServices(IServiceCollection services)
{
// Additional configs above...
services.AddCors(options =>
{
options.AddPolicy("AllowAnyOrigin", builder =>
{
// Allow "Access-Control-Allow-Origin: *" header
builder.AllowAnyOrigin();
});
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Add this above other config options...
app.UseCors("AllowAnyOrigin");
}

我知道这听起来很疯狂,但对我来说是[ HttpPost ()]而不是[ HttpPost ]。当我去掉多余的括号时,它就开始工作了