如何解决.NET Core API访问服务器文件夹时的CORS错误?
问题描述
图片可正常上传至服务器Uploads文件夹,但访问该文件夹内的图片时出现CORS错误。环境为IIS 10,应用基于.NET Core API,相关代码及服务器配置如下:
.NET Core API 代码
using PortalApp.Contracts.Data.Dtos.Custom; using PortalApp.Data; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.FileProviders; using Microsoft.IdentityModel.Tokens; using System.Net.Sockets; using System.Net; using System.Text; using Microsoft.AspNetCore.Cors.Infrastructure; var builder = WebApplication.CreateBuilder(args); var MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; builder.Services.AddOptions<AppPortalSettings>().BindConfiguration("AppPortalSettings"); builder.Services.AddDbContext<AppPortalDatabaseContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddDbContext<AppPortalDatabaseContext>(); builder.Services.AddCustomServices(); builder.Services.AddMapper(); builder.Services.AddCors(); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { var key = builder.Configuration["AppPortalSettings:Key"]; var issuer = builder.Configuration["AppPortalSettings:Issuer"]; var audience = builder.Configuration["AppPortalSettings:Issuer"]; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateIssuerSigningKey = true, ValidateLifetime = true, ValidIssuer = issuer, ValidAudience = audience, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)) }; }); builder.Services.AddControllers(); builder.Services.AddCors(options => { options.AddPolicy(name:"Policy1", builder => { builder.SetIsOriginAllowed(origin => new Uri(origin).Host == "localhost") .AllowAnyHeader().AllowAnyMethod(); }); options.AddPolicy("MyCorsPolicy", builder => builder .SetIsOriginAllowedToAllowWildcardSubdomains() .WithOrigins("https://*.", "http://*.") .AllowAnyMethod() .AllowCredentials() .AllowAnyHeader() .Build() ); options.AddPolicy(name: MyAllowSpecificOrigins, builder => builder .SetIsOriginAllowedToAllowWildcardSubdomains() .WithOrigins("http://15x.xxx.xxx.xxx:6065/", "http://*.") .AllowAnyMethod() .AllowCredentials() .AllowAnyHeader() .Build() ); }); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddHttpContextAccessor(); builder.Services.AddMemoryCache(); var app = builder.Build(); app.UseSwagger(); app.UseSwaggerUI(); #region Use Static Files try { app.UseStaticFiles(); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider( Path.Combine(builder.Environment.ContentRootPath, "Uploads")), RequestPath = "/Uploads" }); } catch (Exception ex) { Console.WriteLine(ex.Message + ex.StackTrace); } #endregion app.UseHttpsRedirection(); app.UseCors(); app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
IIS Web 配置(web.config)
<?xml version="1.0" encoding="utf-8"?> <configuration> <location path="." inheritInChildApplications="false"> <system.webServer> <modules> <remove name="WebDAVModule" /> </modules> <handlers> <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" /> </handlers> <aspNetCore processPath="dotnet" arguments=".\App.Api.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess"/> </system.webServer> </location> </configuration> <!--ProjectGuid: f75f628c-d8f8-41eb-b53c-9b9ec6e5a000-->
解决方案
1. 调整中间件顺序,确保CORS优先于静态文件
CORS中间件必须在UseStaticFiles之前执行,否则静态文件请求不会经过CORS校验。修改后的中间件顺序如下:
var app = builder.Build(); app.UseSwagger(); app.UseSwaggerUI(); // 先启用CORS app.UseHttpsRedirection(); // 指定使用已定义的策略,比如MyAllowSpecificOrigins app.UseCors(MyAllowSpecificOrigins); // 再处理静态文件 #region Use Static Files try { app.UseStaticFiles(); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider( Path.Combine(builder.Environment.ContentRootPath, "Uploads")), RequestPath = "/Uploads" }); } catch (Exception ex) { Console.WriteLine(ex.Message + ex.StackTrace); } #endregion app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
2. 清理重复的CORS配置
当前代码中多次调用UseCors(无参数版本+临时策略)会导致配置冲突,保留一个明确的策略调用即可,比如使用你定义的MyAllowSpecificOrigins策略。
3. 修正Origin地址格式
WithOrigins中的URL不要带末尾斜杠,比如把"http://15x.xxx.xxx.xxx:6065/"改为"http://15x.xxx.xxx.xxx:6065",否则可能导致Origin匹配失败。
4. 可选:IIS层面补充CORS配置(若代码配置未生效)
如果.NET Core的CORS配置仍未生效,可以在web.config的system.webServer节点下添加CORS全局配置:
<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Methods" value="GET,POST,OPTIONS" /> <add name="Access-Control-Allow-Headers" value="Content-Type" /> </customHeaders> </httpProtocol>
注意:这种方式是全局配置,建议优先使用.NET Core代码层面的配置,更灵活可控。
内容的提问来源于stack exchange,提问作者Zidane
相关产品推荐
相关产品推荐

