一、在Startup.cs 的 ConfigureServices 配置好跨域策略
public void ConfigureServices(IServiceCollection services) { //添加cors services.AddCors(options => { //添加core 策略 options.AddPolicy("Policy1", //策略名 builder => { builder.WithOrigins("*", //表示可以被所有地址跨域访问 "http://localhost:3000",//允许跨域访问的地址,不能以正反斜杠结尾。 "http://*.localhost:3001") .SetIsOriginAllowedToAllowWildcardSubdomains()//设置策略里的域名允许通配符匹配,但是不包括空。 //例:http://localhost:3001 不会被通过 // http://xxx.localhost:3001 可以通过 .AllowAnyHeader()//配置请求头 .AllowAnyMethod();//配置允许任何 HTTP 方法访问 }); //添加另外一个 core 策略 添加多个策略可以为不同域名的源进行配置。 策略名不能重复 options.AddPolicy("Policy2", builder => { builder.WithOrigins("http://www.contoso.com") .AllowAnyHeader() .AllowAnyMethod(); }); }); services.AddControllers(); }
二、在Startup.cs 的 Configure开启跨域。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); //使用cors,注意中间件的位置位于UseRouting与UserAuthorization之间 app.UseCors();//此处如果填写了app.UserCors("Policy1"),则控制器中默认使用该策略,并且不需要在控制器上添加[EnableCors("Policy1")] app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
三、在控制器中设置跨域策略。
在微软的文档中,可以配置通用跨域,即无需编写跨域策略,开启所有源都可以跨域访问,则无需在控制器中设置是否开启跨域。
这里使用的方法,可以对每个控制器和Action 都可以设置是否允许跨域,更为安全灵活
1.在控制器类上添加[EnableCors("Policy1")] 属性。
[ApiController] [Route("[controller]")] [EnableCors("Policy1")] //表示在该控制器下所有Action 都可被满足“Policy1”策略的源跨域访问。 public class WeatherForecastController : ControllerBase { [HttpGet] public string Get(){ return "get"; } [HttpPost] public string Post() { return "post"; } }
表示在该控制器下所有Action 都可被满足“Policy1”策略的源跨域访问。
2.在Action 方法上添加[EnableCors("Policy1")] 属性。
[ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { [EnableCors("Policy1")] //表示Get方法可以被满足“Policy1”策略的源跨域访问,而同控制器下的Post方法不可。 [HttpGet] public string Get(){ return "get"; } [HttpPost] public string Post() { return "post"; } }
表示Get方法可以被满足“Policy1”策略的源跨域访问,而同控制器下的Post方法不可。
3.在控制器基类中添加[EnableCors("Policy1")] 属性
//基类 [EnableCors("Policy1")] public class BaseController:ControllerBase { }
//控制器类 [ApiController] [Route("[controller]")] public class WeatherForecastController : BaseController { [HttpGet] public string Get(){ return "get"; } [HttpPost] public string Post() { return "post"; } }
此时WeatherForecastController 继承次添加了 [EnableCors("Policy1")]属性的 BaseController,所以WeatherForecastController 下的所有Action 都可被满足“Policy 1” 策略的源访问。
[ApiController] [Route("[controller]")] public class WeatherForecastController : BaseController { [HttpGet] public string Get(){ return "get"; } [HttpPost] public string Post() { return "post"; } [DisableCors] [HttpDelete] public string Delete() { return "delete"; } }
此时delete方法因添加[DisabelCors] 属性 而不启用所属控制器从父类继承过来的跨域策略。
四、CORS 策略选项(配置cors策略时可以设置)
设置允许的 HTTP 方法
options.AddPolicy("Policy1", builder => { builder.WithOrigins("http://localhost:3000") .WithMethods("POST","DELETE");//允许所有则直接使用:AllowAnyMethod() });
设置允许的请求标头
options.AddPolicy("Policy1", builder => { builder.WithOrigins("http://localhost:3000") .WithHeaders(HeaderNames.ContentType, "x-custom-header"); //当设置WithHeaders时,请求源的标头需与设置的标头完全匹配 策略才能生效。 //允许所有则直接使用:AllowAnyHeader() });