net core 3.1 添加cors,解决跨域问题
1、什么是跨域
解决跨域问题,我们得先了解一下,什么是域,什么又是跨域
域:也就是域名
跨域:浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域,如:
这两个URL同源:
https://example.com/foo.html https://example.com/bar.html
这些 URL 的源与前两个 URL对比, 跨域了:
https://example.net:不同的域 https://www.example.com/foo.html:不同的子域 http://example.com/foo.html:不同的协议 https://example.com:9000/foo.html:不同的端口
本地跨域补充:
localhost和127.0.0.1虽然都指向本机,但也属于跨域
2、CORS请求,简单请求和非简单请求
2.1,简单请求(simple request)
满足一下两个条件,即为简单请求
1)请求方法是以下三种方法之一: HEAD GET POST 2)HTTP的头信息不超出以下几种字段: Accept Accept-Language Content-Language Last-Event-ID Content-Type:只限于三个值 application/x-www-form-urlencoded(对发送内容进行编码) multipart/form-data(上传的表单内包含文件) text/plain(发送内容为纯文本格式)
对于简单请求,浏览器会直接发出CORS字段,具体来说,就是在头部添加Origin信息,标记来源(也就是当前web的【协议 + 域名 + 端口】)
2.2,非简单请求(not-so-simple request)
不满足2.1,即为非简单请求
在正式通信之前,浏览器自动发送一个OPTION请求(也叫做预检操作)
服务器收到预检请求后,检查这些特殊的请求方法和头自己能否接受。如果服务器支持预检中的Header和Methods,那么接下来就可以正常发送信息。
3、解决跨域问题:
PS:微软官方文档
https://learn.microsoft.com/zh-cn/aspnet/core/security/cors?view=aspnetcore-3.1
跨域问题,需要关注几个平台
3.1 后台资源(API),授权跨域操作(Net core 3.1)
首先,定义服务,ConfigureServices
//允许跨域 services.AddCors(options => { options.AddPolicy("any", policy => //any为自定义策略名,允许任意访问,有一定风险
{ policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod(); }); options.AddPolicy("_myAllowSpecificOrigins,policy" => //只授权来访地址,安全性比较高 { policy.WithOrigins("https://XXXXX.com.cn","http://YYYYY.com") .AllowAnyHeader().AllowAnyMethod(); }); });
然后注册中间件:CORS 中间件必须配置为在对 UseRouting
和 UseEndpoints
的调用之间执行
Configure
app.UseRouting(); app.UseCors("any"); //将自己定义的策略注册进来 app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
完成!!!
补充:可用通过在接口添加特性,将策略细分到每个接口,如:
[EnableCors("_myAllowSpecificOrigins")] [HttpGet] public ActionResult<IEnumerable<string>> Get() { return new string[] { "green widget", "red widget" }; }
3.2 前端,授权跨域操作
web界面的静态资源,有可能涉及跨源,加上:
<meta http-equiv="Access-Control-Allow-Origin" content="*">
3.3 网关,需要允许Option请求
当我们确实做好前后端允许跨域,却还出现跨域问题时,需要关注一下,是不是被中间的网关拦截了
(我这个是现实遇到的问题,内网访问正常,外网却提示跨域)
前面说过,跨域请求的“非简单请求”会首先发送一次OPTION请求(预检操作)到服务器,等待服务器告知正常才正式执行请求。
所以,务必务必,在网关设置允许的HTTP方法里,添加选择OPTION