CORS
- 是一种 W3C 标准,可让服务器放宽相同的源策略。
- 不 是一项安全功能,CORS 放宽 security。 API 不能通过允许 CORS 来更安全。 有关详细信息,请参阅 CORS 的工作原理。
- 允许服务器明确允许一些跨源请求,同时拒绝其他请求。
- 比早期的技术(如 JSONP)更安全且更灵活。
同域和不同域
如果两个 Url 具有相同的HTTP访问协议、主机和端口 ,则它们具有相同的域。
这两个 Url 为同域:
下面的Url为不同的域:
https://example.net
:不同的域名https://www.example.com/foo.html
:不同的子域http://example.com/foo.html
:不同Http协议https://example.com:9000/foo.html
:不同的端口
跨域的问题
当不同域的请求发生时,会出现如下提示信息:
Access to XMLHttpRequest at 'https://localhost:15001/api/dashboard/' from origin 'https://localhost:5001' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
注意关键词,CORS,其他的可以不关注。
解决跨域问题(NET 5)
1. 通过中间件和策略配置实现跨域
废话少说,先看代码.public class Startup { readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy(name: MyAllowSpecificOrigins, builder => { builder.WithOrigins("http://example.com", "http://www.contoso.com"); }); }); // services.AddResponseCaching(); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseCors(MyAllowSpecificOrigins); // app.UseResponseCaching(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
NOTE:
- MyAllowSpecificOrigins 这个是跨域策略的名字,您随意。如果不喜欢,可以使用 AddDefaultPolicy 替换,可以不指定名字。
- UseCors 方法必须要在
UseRouting
之后,但是在UseAuthorization
之前。UseCors 方法需要传入策略名字,如果不喜欢,可以在终结点注册时,使用 RequireCors(MyAllowSpecificOrigins)
2.通过属性实现跨域
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy("Policy1", builder => { builder.WithOrigins("http://example.com", "http://www.contoso.com"); }); options.AddPolicy("AnotherPolicy", builder => { builder.WithOrigins("http://www.contoso.com") .AllowAnyHeader() .AllowAnyMethod(); }); }); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseCors(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
[Route("api/[controller]")] [ApiController] public class WidgetController : ControllerBase { // GET api/values [EnableCors("AnotherPolicy")] [HttpGet] public ActionResult<IEnumerable<string>> Get() { return new string[] { "green widget", "red widget" }; } // GET api/values/5 [EnableCors("Policy1")] [HttpGet("{id}")] public ActionResult<string> Get(int id) { return id switch { 1 => "green widget", 2 => "red widget", _ => NotFound(), }; } }
NOTE
[EnableCors]
使用默认跨域策略[EnableCors("{Policy String}")]
使用相应名字的跨越策略.
[EnableCors]
可以用在
- Razor Page
PageModel
- Controller
- Controller action method