【问题标题】:MVC Web API Angular App ('http://localhost:4200' has been blocked by CORS policy)MVC Web API Angular App(“http://localhost:4200”已被 CORS 策略阻止)
【发布时间】:2019-11-16 19:34:42
【问题描述】:

我一直在寻找一种方法让我的前端 Web 应用程序 (Angular) 能够访问我的 Asp.NET MVC(控制器),但它显示以下错误:

访问 XMLHttpRequest 在 'https://localhost:44344/Authentication/SignIn' 来自原点 'http://localhost:4200' 已被 CORS 策略阻止:响应 预检请求未通过访问控制检查:它没有 HTTP 正常状态。

角度网址:http://localhost:4200/login?returnUrl=%2F

MVC 网址:https://localhost:44344/

这也是我添加到我的 web.config 中的内容

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="http://localhost:4200" />
    <add name="Access-Control-Allow-Headers" value="*" />
    <add name="Access-Control-Allow-Methods" value="*" />
    <add name="Content-Type" value="application/json"/>

    <add name="Access-Control-Allow-Credentials" value="true" />
  </customHeaders>
</httpProtocol>

我还在主控制器中添加了以下行:

 [EnableCors(origins: "http://localhost:4200", headers: "*", methods: "*")]

但是错误是一样的。

这是控件的初始化:

    [HttpPost]
    [AllowAnonymous]
    [DisableCors]
    public JsonResult SignUp(HF_Accnt_Access Company)

谁能帮帮我。

【问题讨论】:

  • 运行 Fiddler (telerik.com/download/fiddler) 或您选择的 Web 调试器并查看流量。有一个预检请求发生,它没有返回 200 OK。返回的状态是什么?
  • 在错误中,您的地址是https,但您配置了http

标签: asp.net-mvc angular http asp.net-web-api cors


【解决方案1】:

将以下代码添加到 App_start 文件夹内 WebApiConfig.cs 文件中的 Register 方法中。

var cors = new EnableCorsAttribute(origins: "", headers: "", methods: "*");

config.EnableCors(cors);

注意: 如果您在任何地方添加任何跨源配置,请从那里删除。 例如:从 web.config 文件中删除。 添加以下代码。

    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute(origins: "*", headers: "*", methods: "*");
        config.EnableCors(cors);
        
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

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

【讨论】:

    【解决方案2】:

    并非所有浏览器都支持 Access-Control-Allow-Methods 的通配符。

    浏览器支持也被 MDN here跟踪

    所以改变这一行

    [EnableCors(origins: "http://localhost:4200", headers: "*", methods: "*")]
    

     [EnableCors(origins: "*", headers: "*", methods: "GET, POST, PUT, DELETE, OPTIONS")]
    

    您必须在 global.asax 中单独处理 "OPTIONS" 方法,因为浏览器会向服务器发送飞行前请求

     protected void Application_BeginRequest()
        {
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
                HttpContext.Current.Response.End();
            }
        }
    

    【讨论】:

      【解决方案3】:

      正如 Rick Strahl 在他的 web blog 中很好解释的那样,问题是: Angular 的默认工作环境在一个单独的端口上运行开发服务器,该端口实际上是一个单独的域,并且所有有效地返回到主 ASP.NET 站点以进行 API 调用的调用都是跨域调用。唉,这些调用失败了,经过仔细检查,这是由于没有发送 CORS 标头。 所以解决办法是:

      // Add service and create Policy with options
      public void ConfigureServices(IServiceCollection services)
      {   
          services.AddCors(options =>
          {
              options.AddPolicy("CorsPolicy",
                  builder => builder.AllowAnyOrigin()
                  .AllowAnyMethod()
                  .AllowAnyHeader()
                  .AllowCredentials() );
          });        
          services.AddMvc(); 
      }
      

      然后您可以将其全局分配给所有控制器或单独的控制器,如下所示。

      1. 全局分配

        public void Configure(IApplicationBuilder app){  
        
            // global policy - assign here or on each controller
        
            app.UseCors("CorsPolicy");
        
            // IMPORTANT: Make sure UseCors() is called BEFORE this
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
        
      2. 单独分配

        [EnableCors("CorsPolicy")]
        public class TestController : Controller
        

      你可能会遇到这个错误:

      CORS 协议不允许同时指定通配符(任何)来源和凭据。如果需要支持凭据,则通过列出各个来源来配置策略

      只需从服务中删除 allowCredentials() 即可。

      希望对你有帮助。

      【讨论】:

        猜你喜欢
        • 2019-12-29
        • 2021-10-08
        • 2020-01-26
        • 1970-01-01
        • 2019-11-17
        • 2019-10-13
        • 2019-10-31
        • 2020-10-31
        • 2020-07-09
        相关资源
        最近更新 更多