簡體   English   中英

Asp.Net WebApi2 啟用 CORS 不適用於 AspNet.WebApi.Cors 5.2.3

[英]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 鏈接以查看標題。 這是一個解釋。

Global.ascx

所有這些都是調用WebApiConfig 它只不過是代碼組織。

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        WebApiConfig.Register(GlobalConfiguration.Configuration);
    }
}

WebApiConfig.cs

此處的關鍵方法是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM