![](/img/trans.png)
[英]CORS Error in Angular BotDetect with ASP.NET WebApi2 backend
[英]Asp.Net WebApi2 Enable CORS not working with AspNet.WebApi.Cors 5.2.3
我嘗試按照http://enable-cors.org/server_aspnet.html 中的步驟讓我的 RESTful API(使用 ASP.NET WebAPI2 實現)處理跨源請求(啟用 CORS)。 除非我修改 web.config,否則它不起作用。
我安裝了 WebApi Cors 依賴項:
install-package Microsoft.AspNet.WebApi.Cors -ProjectName MyProject.Web.Api
然后在我的App_Start
我已經得到了類WebApiConfig
如下:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var corsAttr = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(corsAttr);
var constraintsResolver = new DefaultInlineConstraintResolver();
constraintsResolver.ConstraintMap.Add("apiVersionConstraint", typeof(ApiVersionConstraint));
config.MapHttpAttributeRoutes(constraintsResolver);
config.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(config));
//config.EnableSystemDiagnosticsTracing();
config.Services.Replace(typeof(ITraceWriter), new SimpleTraceWriter(WebContainerManager.Get<ILogManager>()));
config.Services.Add(typeof(IExceptionLogger), new SimpleExceptionLogger(WebContainerManager.Get<ILogManager>()));
config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());
}
}
但在那之后我運行應用程序,我用 Fiddler 請求一個資源,如: http://localhost:51589/api/v1/persons並且在響應中我看不到我應該看到的 HTTP 標頭,例如:
Access-Control-Allow-Methods: POST, PUT, DELETE, GET, OPTIONS
Access-Control-Allow-Origin: *
我錯過了一些步驟嗎? 我嘗試在控制器上使用以下注釋:
[EnableCors(origins: "http://example.com", headers: "*", methods: "*")]
結果相同,未啟用 CORS。
但是,如果我在 web.config 中添加以下內容(甚至沒有安裝 AspNet.WebApi.Cors 依賴項),它就可以工作:
<system.webServer>
<httpProtocol>
<!-- THESE HEADERS ARE IMPORTANT TO WORK WITH CORS -->
<!--
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="POST, PUT, DELETE, GET, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="content-Type, accept, origin, X-Requested-With, Authorization, name" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
-->
</httpProtocol>
<handlers>
<!-- THESE HANDLERS ARE IMPORTANT FOR WEB API TO WORK WITH GET,HEAD,POST,PUT,DELETE and CORS-->
<!--
<remove name="WebDAV" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
-->
</handlers>
任何幫助將非常感激!
謝謝你。
我為您創建了一個精簡的演示項目。
您可以從本地 Fiddler 嘗試上述API 鏈接以查看標題。 這是一個解釋。
所有這些都是調用WebApiConfig
。 它只不過是代碼組織。
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
WebApiConfig.Register(GlobalConfiguration.Configuration);
}
}
此處的關鍵方法是EnableCrossSiteRequests
方法。 這就是您需要做的所有事情。 EnableCorsAttribute
是一個全局范圍的 CORS 屬性。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
EnableCrossSiteRequests(config);
AddRoutes(config);
}
private static void AddRoutes(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "Default",
routeTemplate: "api/{controller}/"
);
}
private static void EnableCrossSiteRequests(HttpConfiguration config)
{
var cors = new EnableCorsAttribute(
origins: "*",
headers: "*",
methods: "*");
config.EnableCors(cors);
}
}
Get
方法接收我們全局應用的EnableCors
屬性。 Another
方法覆蓋全局EnableCors
。
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] {
"This is a CORS response.",
"It works from any origin."
};
}
// GET api/values/another
[HttpGet]
[EnableCors(origins:"http://www.bigfont.ca", headers:"*", methods: "*")]
public IEnumerable<string> Another()
{
return new string[] {
"This is a CORS response. ",
"It works only from two origins: ",
"1. www.bigfont.ca ",
"2. the same origin."
};
}
}
您不需要在 web.config 中添加任何特殊內容。 事實上,這就是演示的 web.config 的樣子——它是空的。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
</configuration>
var url = "https://cors-webapi.azurewebsites.net/api/values" $.get(url, function(data) { console.log("We expect this to succeed."); console.log(data); }); var url = "https://cors-webapi.azurewebsites.net/api/values/another" $.get(url, function(data) { console.log(data); }).fail(function(xhr, status, text) { console.log("We expect this to fail."); console.log(status); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
您只需要更改一些文件。 這對我有用。
Global.ascx
public class WebApiApplication : System.Web.HttpApplication {
protected void Application_Start()
{
WebApiConfig.Register(GlobalConfiguration.Configuration);
} }
WebApiConfig.cs
所有請求都必須調用此代碼。
public static class WebApiConfig {
public static void Register(HttpConfiguration config)
{
EnableCrossSiteRequests(config);
AddRoutes(config);
}
private static void AddRoutes(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "Default",
routeTemplate: "api/{controller}/"
);
}
private static void EnableCrossSiteRequests(HttpConfiguration config)
{
var cors = new EnableCorsAttribute(
origins: "*",
headers: "*",
methods: "*");
config.EnableCors(cors);
} }
一些控制器
沒什么可改變的。
網頁配置
您需要在 web.config 中添加處理程序
<configuration>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
</configuration>
在 CORS 請求的情況下,所有現代瀏覽器都使用 OPTION 動詞進行響應,然后實際的請求會繼續執行。 這應該用於在 CORS 請求的情況下提示用戶進行確認。 但是對於 API,如果您想跳過此驗證過程,請將以下代碼段添加到 Global.asax
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
在這里,我們只是通過檢查 OPTIONS 動詞來通過檢查。
我剛剛在 Web.config 中添加了自定義標頭,它就像一個魅力。
在配置上 - system.webServer:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
我在同一個解決方案上有前端應用程序和后端。 為此,我需要將 Web 服務項目(后端)設置為默認設置才能使其正常工作。
我正在使用 ReST,還沒有嘗試過其他任何東西。
在對我的 Web.config CORS 進行一些修改后,我的 Web API 2 項目突然停止工作(至少對於預檢期間的 OPTIONS 請求)。 似乎您需要在 Web.config 中包含下面提到的部分,否則(全局)EnableCorsAttribute 將無法處理 OPTIONS 請求。 請注意,這與 Visual Studio 將添加到新 Web API 2 項目中的部分完全相同。
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
<remove name="OPTIONSVerbHandler"/>
<remove name="TRACEVerbHandler"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
</handlers>
</system.webServer>
我剛剛遇到了同樣的問題,試圖在全球范圍內啟用 CORS 。 但是我發現它確實有效,但是僅當請求包含Origin
標頭值時。 如果您省略origin
標頭值,則響應將不包含Access-Control-Allow-Origin
。
我使用了一個名為DHC的 chrome 插件來測試我的 GET 請求。 它允許我輕松添加Origin
標頭。
這些答案都沒有真正奏效。 正如其他人指出的那樣,如果請求具有 Origin 標頭,則 Cors 包將僅使用 Access-Control-Allow-Origin 標頭。 但是您通常不能只向請求添加 Origin 標頭,因為瀏覽器也可能會嘗試對其進行規范。
如果您想要一種快速而骯臟的方式來允許對 Web api 的跨站點請求,那么編寫自定義過濾器屬性確實要容易得多:
public class AllowCors : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext == null)
{
throw new ArgumentNullException("actionExecutedContext");
}
else
{
actionExecutedContext.Response.Headers.Remove("Access-Control-Allow-Origin");
actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
}
base.OnActionExecuted(actionExecutedContext);
}
}
然后只需在您的 Controller 操作上使用它:
[AllowCors]
public IHttpActionResult Get()
{
return Ok("value");
}
我不會保證一般情況下的安全性,但它可能比在 web.config 中設置標頭安全得多,因為這樣你可以只在你需要的時候具體應用它們。
當然,修改上述內容以僅允許某些來源、方法等很簡單。
沒有一個安全的解決方案對我有用,所以比 Neeraj 更安全,比 Matthew 更容易,只需添加: System.Web.HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
在您的控制器方法中。 那對我有用。
public IHttpActionResult Get()
{
System.Web.HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
return Ok("value");
}
我發現這個問題是因為我遇到了大多數瀏覽器發送的 OPTIONS 請求的問題。 我的應用程序正在路由 OPTIONS 請求並使用我的 IoC 來構造大量對象,並且由於各種原因,有些人在這種奇怪的請求類型上拋出異常。
如果所有 OPTIONS 請求給您帶來問題,則基本上為它們設置一個忽略路由:
var constraints = new { httpMethod = new HttpMethodConstraint(HttpMethod.Options) };
config.Routes.IgnoreRoute("OPTIONS", "{*pathInfo}", constraints);
更多信息: 停止 Web API 處理 OPTIONS 請求
希望這對未來的人有所幫助。 我的問題是我正在遵循與 OP 相同的教程來啟用全局 CORS。 但是,我還在 AccountController.cs 文件中設置了特定於操作的 CORS 規則:
[EnableCors(origins: "", headers: "*", methods: "*")]
並且收到有關來源的錯誤不能為空或空字符串。 但是錯誤發生在所有地方的 Global.asax.cs 文件中。 解決方案是將其更改為:
[EnableCors(origins: "*", headers: "*", methods: "*")]
注意起源中的 * 嗎? 缺少它是導致 Global.asax.cs 文件中出現錯誤的原因。
希望這可以幫助某人。
WEBAPI2:解決方案。 global.asax.cs:
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
在解決方案資源管理器中,右鍵單擊 api-project。 在屬性窗口中將“匿名身份驗證”設置為已啟用!!!
希望這對未來的人有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.