[英]Dotnet core 3.0 project encounter cors issue because of configuration in startup.cs for uploading file function
The frontend is react project and backend is dotnet core, they are hosted in different places, that's why I need to configure the cors in startup.cs in my dotnet project.前端是react项目,后端是dotnet core,它们托管在不同的地方,这就是为什么我需要在我的dotnet项目的startup.cs中配置cors。
The problem is very weird.问题很奇怪。 After configuration, there is no cors issue if I run the project in my local environment(on my: pc-frontend and backend), however, on the testing server, every request from the frontend encounter cors error.
配置后,如果我在本地环境(在我的:pc-frontend 和 backend)上运行项目,则没有 cors 问题,但是,在测试服务器上,来自前端的每个请求都会遇到 cors 错误。 The error message from console is something like this:
来自控制台的错误消息是这样的:
Access to XMLHttpRequest at 'http://dummybackend.com' from origin 'http://dummyfrontend.com' 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. CORS 策略已阻止从源“http://dummyfrontend.com”访问“http://dummybackend.com”上的 XMLHttpRequest 策略:对预检请求的响应未通过访问控制检查:否“访问控制允许” -Origin' header 存在于请求的资源上。
After a whole day's research, I found the problem has someting to do with one part of the configuration, which is app.UseStaticFiles,经过一整天的研究,我发现问题与配置的一部分有关,即app.UseStaticFiles,
app.UseStaticFiles(new StaticFileOptions()
{
ServeUnknownFileTypes = true,
OnPrepareResponse = (ctx) =>
{
var policy = corsPolicyProvider.GetPolicyAsync(ctx.Context, "CorsPolicy")
.ConfigureAwait(false)
.GetAwaiter().GetResult();
var corsResult = corsService.EvaluatePolicy(ctx.Context, policy);
corsService.ApplyResult(corsResult, ctx.Context.Response);
},
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"Uploads")),
RequestPath = new PathString("/StaticFiles"),
});
which is the configuration for file uploading.这是文件上传的配置。 If I comment this out, there is no cors issue on the testing server(AWS EC2), but of course, I need this for successful file submitting.
如果我将此注释掉,则测试服务器(AWS EC2)上没有 cors 问题,但当然,我需要这个才能成功提交文件。
I've found one solution from this blog https://www.bytefish.de/blog/aspnetcore_static_files_cors.html我从这个博客https://www.bytefish.de/blog/aspnetcore_static_files_cors.html找到了一个解决方案
But it doesn't work但它不起作用
Below is the configuration I made based on the blog.下面是我根据博客做的配置。
public void ConfigureServices(IServiceCollection services)
{
// Add CORS:
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", policyBuilder => policyBuilder
.WithOrigins("http://dummyfrontend.com", "http://localhost:8080")
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
SetConfigurations();
services.AddDbContext<DBContext>(options => options.UseMySql(Configuration.GetConnectionString("LocalDatabase")), ServiceLifetime.Transient);
services.AddDbContext<DBContextMail>(options => options.UseMySql(Configuration.GetConnectionString("MailDatabase")), ServiceLifetime.Transient);
services.AddControllers().AddNewtonsoftJson();
services.Configure<JWT>(Configuration.GetSection("JWT"));
services.AddScoped<IUserService, UserService>();
services.AddScoped<IAffiliateService, AffiliateService>();
services.AddScoped<ICommissionService, CommissionService>();
services.AddScoped<IReferrerProfileService, ReferrerProfileService>();
services.AddScoped<IApplicationService, ApplicationService>();
services.AddScoped<IDashboardService, DashboardService>();
services.AddScoped<ITeamService, TeamService>();
services.AddScoped<IHistoryService, HistoryService>();
services.AddScoped<IScheduleService, ScheduleService>();
services.AddScoped<ISettingService, SettingService>();
services.AddScoped<IUserRolesService, UserRolesService>();
services.AddScoped<IEmailTemplateService, EmailTemplateService>();
services.AddScoped<ISMSTemplateService, SMSTemplateService>();
services.AddScoped<IImportReferrersService, ImportReferrersService>();
if (Environment.IsDevelopment())
{
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1.0", new OpenApiInfo { Title = "Referrer Api v1.0", Version = "v1.0" });
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement {
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] { }
}
});
c.CustomSchemaIds(type => type.FullName);
var filePath = Path.Combine(System.AppContext.BaseDirectory, "ReferralSystem.xml");
c.IncludeXmlComments(filePath);
});
services.AddSwaggerGenNewtonsoftSupport();
}
var key = Encoding.ASCII.GetBytes(Configuration.GetSection("JWT").Get<JWT>().Secret);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
services.Configure<FormOptions>(o =>
{
o.ValueLengthLimit = int.MaxValue;
o.MultipartBodyLengthLimit = int.MaxValue;
o.MemoryBufferThreshold = int.MaxValue;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, ICorsService corsService, ICorsPolicyProvider corsPolicyProvider)
{
app.UseRouting();
loggerFactory.AddLog4Net();
app.UseCors("CorsPolicy");
// To serve PBF Files, we need to allow unknown filetypes
// to be served by the Webserver:
if (env.IsDevelopment())
{
app.UseHttpsRedirection();
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1.0/swagger.json", "Referrer Api V1.0");
c.DocumentTitle = "Referrer System API Document";
c.DocExpansion(DocExpansion.None);
});
}
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseStaticFiles(new StaticFileOptions()
{
ServeUnknownFileTypes = true,
OnPrepareResponse = (ctx) =>
{
var policy = corsPolicyProvider.GetPolicyAsync(ctx.Context, "CorsPolicy")
.ConfigureAwait(false)
.GetAwaiter().GetResult();
var corsResult = corsService.EvaluatePolicy(ctx.Context, policy);
corsService.ApplyResult(corsResult, ctx.Context.Response);
},
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"Uploads")),
RequestPath = new PathString("/StaticFiles"),
});
}
I found the solution myself, it is because inside the app.UseStaticFiles configuration, I define a folder which is @"Uploads", and after publishing the project, there is no such folder inside the publish folder, therefore, the project encounter startup exception.我自己找到了解决办法,是因为在app.UseStaticFiles配置里面,我定义了一个文件夹,就是@"Uploads",而发布项目后,发布文件夹里面没有这个文件夹,所以项目遇到启动异常.
The solution is simply manually add the folder in the published file folder, so that the project wont encounter startup exception.解决方法就是在发布的文件夹中手动添加文件夹,这样项目就不会遇到启动异常了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.