来自源的 Angular 和 WebApi Cors 请求已被 CORS 策略阻止

时间:2021-07-03 13:56:35

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

我有一个角度应用程序 (角版本 角 CLI:8.3.26 节点:10.13.0 操作系统:win32 x64 角度:8.2.14)

在 environment.ts 中,我有与后端的链接

    export const environment = {
      baseUrlNG: 'http://localhost:4200/',
      baseUrlApi: 'http://localhost:8082/backend/api/'
    }

后端是一个 C# WebApi 应用程序。 我使用 Visual Studio 使用此配置对其进行调试。

server configuration

我安装了 nuget Microsoft.AspNet.WebApi.Cors 并且在文件 WebApiConfig.cs 中我有这个代码:

    public static class WebApiConfig
    {
        [EnableCors(origins: "*", headers: "*", methods: "*")]
        public static void Register(HttpConfiguration config)
        {
            config.EnableCors();

            config.MapHttpAttributeRoutes();

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

            );
        }
    }

在我所有的后端方法中,我都有这个装饰器

    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class AuthenticationController : ApiController
    {
        [Route("api/Authentication/{language}/GuestUser")]
        [HttpPost]
        [Attributes.SiteParameter_Check]
        public IHttpActionResult GuestAuthorization(string language)
        {
            //code with breakpoints never raised.
        }

在 angular 项目中我有这篇文章

    function guest(){
      url =  `${environment.baseUrlApi}Authentication/IT/GuestUser`;
      return this.http.post(url, {}, )
        .toPromise()        
        .then(response => {
              //other code        
        })
    }

我收到此错误

Access to XMLHttpRequest at 'http://localhost:8082/backend/api/Authentication/IT/GuestUser' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

已经尝试将proxy.conf.json文件放在angular项目的src文件夹中

{
    {
        "/api/*": {
        "target": "http://localhost:8082/backend/api",
        "secure": false,
        "logLevel": "debug"
    }
}

我把这一行放在文件 angular.json 中

     "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "frontend:build",
            "proxyConfig": "src/proxy.conf.json"
      },

这是我的网络配置

    <?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=301879
  -->
<configuration>
    <configSections>

        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </configSections>

    <system.web>
        <compilation debug="true" targetFramework="4.6.1" />
        <httpRuntime targetFramework="4.6.1" executionTimeout="1200" maxRequestLength="1048576" useFullyQualifiedRedirectUrl="false" minFreeThreads="8" minLocalRequestFreeThreads="4" appRequestQueueLimit="100" />
    </system.web>
    
    <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>
       
        <validation validateIntegratedModeConfiguration="false" />
        <directoryBrowse enabled="true" />
        
        <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>

    <system.web.extensions>
        <scripting>
            <webServices>
                <jsonSerialization maxJsonLength="2147483647" />
            </webServices>
        </scripting>
    </system.web.extensions>
    
    <connectionStrings>
        ---all my connection strings
    </connectionStrings>
    <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
        <providers>
            <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
        </providers>
    </entityFramework>
    
</configuration>

我缺少什么?

非常感谢

4 个答案:

答案 0 :(得分:3)

<块引用>

把它放在 WebApiConfig 中

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            var cors = new EnableCorsAttribute("*", "*", "*");// origins, headers, methods  
            config.EnableCors(cors);

            config.MapHttpAttributeRoutes();

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

请添加这些引用

使用 Newtonsoft.Json.Serialization;

使用 System.Web.Http.Cors;

注意:WebApiConfig 的改变就足够了。无需任何配置

答案 1 :(得分:1)

我们曾经在 web.config 中有这样的东西。

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

如果我没记错的话,您需要在下面进行设置以允许 ASP.NET 应用程序接收和处理 OPTION。

<system.webServer>
  <handlers>
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="OPTIONSVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  </handlers>
</system.webServer>

所有细节都在这篇文章中。 https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api

答案 2 :(得分:1)

你确定这个端口是服务器监听的端口吗?

不久前我也遇到过类似的情况(但使用 java 和 Jboss),其中 api-url 的端口和侦听端口不同。

就我而言:

  • Api-url 的端口:8080
  • 侦听端口:9990

所以我不得不这样设置代理:

<块引用>

{ "/api/*": { "目标": "http://localhost:9990", “安全”:假, “日志级别”:“调试” } }

答案 3 :(得分:1)

I also recently experienced same kind of issues while doing the same. I'm copying my MVC API codes here to help you to resolve the same. Kindly configure the same accordingly so that issue will be resolved.

WebApiConfig.cs file

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

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

web.config file (specific node webServer tag showed below)

<system.webServer>
    <modules>
      <remove name="FormsAuthenticationModule" />
    </modules>
    <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" />
        <add name="Access-Control-Allow-Credentials" value="true" />
      </customHeaders>
    </httpProtocol>
    <handlers>
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
      <!--<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" 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>
  </system.webServer>

Add Global.asax file below method (This call specifically for PUT,POST related OPTIONS call.

 protected void Application_BeginRequest(object sender, EventArgs e)
        {
            if (HttpContext.Current.Request.Headers.AllKeys.Contains("Origin") && HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
               //   Response.AddHeader("Access-Control-Allow-Origin", "*");
               // Response.AppendHeader("Access-Control-Allow-Methods", "*");
               // Response.AddHeader("Access-Control-Max-Age", "8000");
                Response.Flush();
            }
        }

If want to restrict in controller level add below decorator in your API controller.

 [EnableCors(origins: "http://locathost:4200", headers: "*", methods: "*")]
    public class AssetsController : ApiController