我有一个在4200本地运行的简单Angular App,我正在测试使用.net core在5000本地运行的Web API。我的startup.cs的CORS配置正确,可以允许我相信的一切。
在ConfigureServices部分中,我有:
services.AddCors();
在“配置”部分中,我有:
app.UseCors(options => options.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());
但是,当我尝试点击我的webapi时,仍然可以在浏览器中找到它。
来自原点“ http://localhost:4200”的信息已被CORS政策阻止:对预检请求的响应未通过访问控制检查:预检请求不允许重定向。
我查看了其他答案,它们似乎都具有我尝试没有改变的这种或类似变化。不确定我还需要做什么?
答案 0 :(得分:5)
startup.cs.Configure()
方法中,app.UseCors()
在app.useMVC()
之前吗? (/)
?Firefox要求为您的API安装一个证书,以便使用HTTPS协议发送Http请求。
使用Postman和浏览器开发人员工具测试您的API。注意2 Http请求。 Http 200是“预检”,用于查看可用的CORS选项。
HTTP 500 (Internal Server Error)
,它将返回开发人员例外页面,而Postman将显示一条“no ‘Access-Control-Allow-Origin’ header is present on the requested resource”
消息-这具有误导性。 AllowAnyOrigin()
。EnableCors
属性配置CORS。 ASP.NET Core 2.2 does not permit allowing credentials with AllowAnyOrigin()
Enable Cross-Origin Requests (CORS) in ASP.NET Core
(/)
。创建Visual Studio解决方案
md c:\s\a cd c:\s\a c:\s\a>dotnet new sln -n solutionName
创建ASP.NET Core项目
c:\s\a>md s c:\s\a>cd s c:\s\a\s>dotnet new webapi -o api -n api
API启动设置和CORS配置
launchSettings.json
将开发配置文件克隆到暂存配置文件
{
"$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"
}
}
}
startup.cs
添加CORS配置
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));
// });
});
}
}
在ValuesController.Get()
上设置断点
使用Postman测试API:
https://localhost:myApiPortNumber/api/values
创建Angular应用程序
c:\s\a\s>ng new Spa1 --routing (will automatically create Spa folder)
启动Spa1应用程序
c:\s\a\s>cd Spa1 c:\s\a\s\Spa1>Ng serve
在Spa1中实现COR
app.module.ts
- 导入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
导入HttpClient
在CORS请求中添加
getValues()
方法
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
补救Firefox块的一种方法:
FireFox |选项|隐私和安全|安全性证书| [查看证书]:
证书经理| [添加例外]:
add localhost
克隆Spa1
c:\s\a\s>xcopy /s /i Spa1 Spa2
重构Spa2的标题
app.component.ts
export class AppComponent implements OnInit {
title = 'Spa2';
}
在端口3200
上启动Spa2应用程序c:\s\a\s\Spa2>ng serve --port 3200
使用开发(IIS Express)配置文件停止调试API
使用登台(IIS Express)配置文件
使用开发人员工具检查Http响应:
答案 1 :(得分:2)
在方法ConfigureServices中添加以下代码段。编辑此选项以仅允许自定义标题。
// Add service and create Policy with options
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
});
在Configure方法中添加以下内容
app.UseCors("CorsPolicy");
向控制器添加“ EnableCors”属性。
[EnableCors("CorsPolicy")]
答案 2 :(得分:1)
在服务中注册cors
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.SetIsOriginAllowed((host) => true)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
添加cors中间件
app.UseCors("CorsPolicy");
答案 3 :(得分:0)
我遇到了同样的问题,但是我的情况是 windowsauthentification 。
@RandyDaddis向我指出了正确的方向。 如果设置了验证,则不能使用“ *”。
但这不能解决孔问题(对我来说'*'不是一个好选择)。
由于preflight未发送凭据,我不得不从仅WindowsAuthentication 更改为混合模式(其中还启用了匿名身份验证)。
这已经是asp讨论的问题。
重要的是,您需要将其添加到 ConfigureServices 函数的 startup.cs 中,以确保所有控制器仍处于授权策略下:
...
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
})...