gpt4 book ai didi

angular - 如何使用 .NET Core 2 配置 Angular 6 以允许来自任何主机的 CORS?

转载 作者:太空狗 更新时间:2023-10-29 17:43:07 25 4
gpt4 key购买 nike

我有一个在 4200 上本地运行的简单 Angular 应用程序,我正在使用 .net 核心在 5000 上本地运行的 web api 进行测试。我的 startup.cs 已正确配置 CORS 以允许我相信的一切。

在 ConfigureServices 部分,我有:services.AddCors();
在配置部分,我有:
app.UseCors(options => options.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());
然而,当我尝试点击我的 webapi 时,我仍然在浏览器中得到这个。

from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.



我查看了其他答案,它们似乎都有我尝试过的这种或类似的变化,没有任何变化。不知道我还需要做什么?

最佳答案

可能的问题:

  • 在您的 startup.cs.Configure()方法,确实 app.UseCors()先于 app.useMVC() ?
  • Http 请求 URL 是否包含结尾斜杠 (/) ?
  • Http 请求是否包含凭据?
  • 浏览器是否从 API 接收 Http 响应?
  • 响应是否包含“Access-Control-Allow-Origin” header ?
  • 当您从 Postman 发送请求时,Http 响应是否包含“Access-Control-Allow-Origin” header 以及包含数据的正文?

  • 陷阱

    Firefox 需要为您的 API 安装证书才能使用 HTTPS 协议(protocol)发送 Http 请求。

    使用 Postman 和浏览器开发工具测试您的 API。注意 2 Http 请求。 Http 200 是一个“预检”,以查看可用的 CORS 选项。
  • 如果您的 API (.NET) 抛出 HTTP 500 (Internal Server Error) ,它将返回一个开发者异常页面,Postman 将显示一个 “no ‘Access-Control-Allow-Origin’ header is present on the requested resource”留言 - 这是误导 .
  • 这种情况下的实际问题是开发者异常页面无法从服务器返回到运行在不同 Origin 上的客户端(浏览器)。

  • 我谨恭敬地指出以下几点:
  • CORS 规范 指出如果存在 Access-Control-Allow-Credentials header ,则将来源设置为“*”(所有来源)是无效的。
  • AllowAnyOrigin()不建议在生产中使用,除非您打算允许任何人使用您的 API 并且您不会实现凭据。
  • 您不需要使用 EnableCors 在 Controller 级别配置 CORS。使用多个 CORS 策略时的属性。
  • 使用 ASP.NET Core 配置多个 CORS 策略很容易( 参见下面的教程 )

  • 以下文章值得回顾:

    ASP.NET Core 2.2 does not permit allowing credentials with AllowAnyOrigin()

    Enable Cross-Origin Requests (CORS) in ASP.NET Core

    要点(tldr;):
  • CORS 中间件必须位于您的应用程序配置中的任何已定义端点之前。
  • 指定的 URL 必须不带斜杠 (/) .
  • 如果浏览器发送凭据但响应不包含
    有效 访问控制允许凭据 标题,浏览器没有
    将响应公开给应用程序,并且跨域请求失败。
  • CORS 规范还指出,将 origins 设置为“*”(所有
    如果 Access-Control-Allow-Credentials header 为
    展示。
  • 如果浏览器支持 CORS,它会自动为跨域请求设置这些 header 。
  • 如果响应不包含 访问控制允许来源 头,跨域请求失败。


  • CORS教程:(二)Angular Clients + ASP.NET Core
  • 创建 Visual Studio 解决方案
    md c:\s\acd c:\s\ac:\s\a>dotnet new sln -n solutionName
  • Create ASP.NET Core Project

    c:\s\a>md sc:\s\a>cd sc:\s\a\s>dotnet new webapi -o api -n api
  • API Launch Settings and CORS Configuration

  • launchSettings.json

    Clone Development Profile to Staging Profile

    {
    "$schema": "http://json.schemastore.org/launchsettings.json",
    "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iis": {
    "applicationUrl": "http://localhost:myIISApiPortNumber",
    "sslPort": myIISApiSSLPortNumber
    },
    "iisExpress": {
    "applicationUrl": "http://localhost:myIISExpressApiPortNumber",
    "sslPort": myIISExpressApiSSLPortNumber
    }
    },
    "profiles": {
    "Development (IIS Express)": {
    "commandName": "IISExpress",
    "launchBrowser": true,
    "launchUrl": "api/values",
    "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development"
    }
    },
    "Staging (IIS Express)": {
    "commandName": "IISExpress",
    "launchBrowser": true,
    "launchUrl": "api/values",
    "applicationUrl": "https://localhost:myIISExpressApiSSLPortNumber;http://localhost:myIISExpressApiPortNumber",
    "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Staging"
    }
    },
    "Production (IIS)": {
    "commandName": "IIS",
    "launchBrowser": true,
    "launchUrl": "api/values",
    "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Production"
    },
    "applicationUrl": "https:localhost:myIISApiSSLPortNumber;http://localhost:myIISApiPortNumber"
    }
    }
    }

    启动.cs

    Add CORS Configuration


    public class Startup
    {
    public IConfiguration Configuration { get; }

    public IServiceCollection _services { get; private set; }

    public Startup(IConfiguration configuration)
    {
    Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
    _services = services;
    RegisterCorsPolicies();
    services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    if (env.IsDevelopment())
    {
    app.UseCors("DevelopmentCorsPolicy");
    app.UseDeveloperExceptionPage();
    }
    else if (env.IsStaging())
    {
    app.UseCors("StagingCorsPolicy");
    }
    else
    {
    app.UseCors("ProductionCorsPolicy");
    app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseMvc(); // CORS middleware must precede any defined endpoints
    }

    private void RegisterCorsPolicies()
    {
    string[] localHostOrigins = new string[] {
    "http://localhost:4200", "http://localhost:3200"};

    string[] stagingHostOrigins= new string[] {
    "http://localhost:4200"};

    string[] productionHostOrigins = new string[] {
    "http://yourdomain.net", "http://www.yourdomain.net",
    "https://yourdomain.net", "https://www.yourdomain.net"};

    _services.AddCors(options => // CORS middleware must precede any defined endpoints
    {
    options.AddPolicy("DevelopmentCorsPolicy", builder =>
    {
    builder.WithOrigins(localHostOrigins)
    .AllowAnyHeader().AllowAnyMethod();
    });
    options.AddPolicy("StagingCorsPolicy", builder =>
    {
    builder.WithOrigins(stagingHostOrigins)
    .AllowAnyHeader().AllowAnyMethod();
    });
    options.AddPolicy("ProductionCorsPolicy", builder =>
    {
    builder.WithOrigins(productionHostOrigins)
    .AllowAnyHeader().AllowAnyMethod();
    });
    //options.AddPolicy("AllowAllOrigins",
    // builder =>
    // {
    // WARNING: ASP.NET Core 2.2 does not permit allowing credentials with AllowAnyOrigin()
    // cref: https://docs.microsoft.com/en-us/aspnet/core/migration/21-to-22?view=aspnetcore-2.2&tabs=visual-studio
    // builder.AllowAnyOrigin()
    // .AllowAnyHeader().AllowAnyMethod();
    // });
    //options.AddPolicy("AllowSpecificMethods",
    // builder =>
    // {
    // builder.WithOrigins(productionHostOrigins)
    // .WithMethods("GET", "POST", "HEAD");
    // });
    //options.AddPolicy("AllowSpecificHeaders",
    // builder =>
    // {
    // builder.WithOrigins(productionHostOrigins)
    // .WithHeaders("accept", "content-type", "origin", "x-custom-header");
    // });
    //options.AddPolicy("ExposeResponseHeaders",
    // builder =>
    // {
    // builder.WithOrigins(productionHostOrigins)
    // .WithExposedHeaders("x-custom-header");
    // });
    //options.AddPolicy("AllowCredentials",
    // WARNING: ASP.NET Core 2.2 does not permit allowing credentials with AllowAnyOrigin() cref: https://docs.microsoft.com/en-us/aspnet/core/migration/21-to-22?view=aspnetcore-2.2&tabs=visual-studio
    // builder =>
    // {
    // builder.WithOrigins(productionHostOrigins)
    // .AllowCredentials();
    // });
    //options.AddPolicy("SetPreflightExpiration",
    // builder =>
    // {
    // builder.WithOrigins(productionHostOrigins)
    // .SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
    // });
    });
    }
    }
  • 使用 开始调试 API开发 (IIS Express) 配置文件

  • ValuesController.Get() 上设置断点
  • 使用 Postman 测试 API:
    https://localhost:myApiPortNumber/api/values
  • 访问控制允许来源 header 和值应在响应
  • 创建 Angular 应用程序
    c:\s\a\s>ng new Spa1 --routing (will automatically create Spa folder)
  • Start Spa1 application

    c:\s\a\s>cd Spa1c:\s\a\s\Spa1>Ng serve
  • Browse to http://localhost:4200/

    • Spa1 should start successfully
  • Implement CORs in Spa1

  • app.module.ts

    • Import HttpClientModule
    import { HttpClientModule } from '@angular/common/http';

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';

    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';

    @NgModule({
    declarations: [
    AppComponent
    ],
    imports: [
    HttpClientModule,
    BrowserModule,
    AppRoutingModule
    ],
    providers: [],
    bootstrap: [AppComponent]
    })
    export class AppModule { }

    app.component.ts

    • Import HttpClient

    • Add getValues() method with CORS Request


    import { Component, OnInit } from '@angular/core';
    import { HttpClient } from '@angular/common/http';

    @Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss']
    })

    export class AppComponent implements OnInit {
    title = 'Spa1';
    values: any;
    apiUrl: string = environment.apiUrl;
    valuesUrl = this.apiUrl + "values";

    constructor(private http: HttpClient) { }

    ngOnInit() {
    this.getValues();
    }
    getValues() {
    this.http.get(this.valuesUrl).subscribe(response => {
    this.values = response;
    }, error => {
    console.log(error);
    });
    }
    }

    app.component.html
    <div style="text-align:center">
    <h1>
    Welcome to {{ title }}!
    </h1>
    </div>
    <h2>Values</h2>
    <p *ngFor="let value of values">
    {{value}}
    </p>
    <router-outlet></router-outlet>

    environment.ts
    export const environment = {
    production: false,
    apiUrl: 'https://localhost:myApiPortNumber/api/'
    };
  • 启动 Spa1 应用程序
    c:\s\a\s\Spa1>Ng serve
  • Browse to http://localhost:4200/

    • Chrome & Edge: should successfully make CORs requests now
    • Safari: I have not tested
    • Firefox: may block request due to un-trusted certificate.
  • One way of remediating the Firefox block:

    FireFox | Options | Privacy & Security | Security | Certificates | [View Certificates] :

    Certificate Manager | [Add Exception]:

       add localhost

    CORS Test

    1. Clone Spa1

      c:\s\a\s>xcopy /s /i Spa1 Spa2
    2. Refactor title of Spa2

    app.component.ts

    export class AppComponent implements OnInit {
    title = 'Spa2';
    }
  • 上启动 Spa2 应用程序端口 3200

    c:\s\a\s\Spa2>ng serve --port 3200
  • 浏览到 http://localhost:3200/
  • values 数组应该在网页上呈现
  • 使用开发 (IIS Express) 配置文件停止调试 API
  • 使用 开始调试 API暂存 (IIS Express) 配置文件
  • 浏览到 http://localhost:4200/
  • 值数组 应该呈现 在网页上。
  • 浏览到 http://localhost:3200/
  • 值数组 不应该渲染 在网页上。
  • 使用开发人员工具检查 Http 响应:
  • 访问控制允许来源 header 和值不应在响应
  • 关于angular - 如何使用 .NET Core 2 配置 Angular 6 以允许来自任何主机的 CORS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54085677/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com