- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章.Net Core Cors中间件的深入讲解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
同源策略和资源跨域共享 。
1、同源策略 。
同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同.
1.1、目的 。
主要是为了保证用户信息的安全,防止网站窃取用户数据。假如没有同源策略,可能就会有下面这种情况的发生。用户访问两个网站A/B,并登录了A网站,A网站会在计算机本地存储Cookie或者Token等等,在访问B网站的时候,B网站就可以访问这些本地的存储信息,B网站可以使用用户的Cookie去登录A网站,那这样用户信息就被泄露了.
1.2、限制范围 。
要知道一点,这些限制其实都是浏览器做的限制.
2、跨域资源共享 。
跨域资源共享跟同源策略相反。在整个跨域通信过程中,浏览器会自动识别此次请求是否跨域,一旦发现跨域,就自动添加请求头信息(如Origin)或者自动发送一次请求方式为option的预请求。浏览器将CORS请求分为两类:简单请求和非简单请求.
2.1、简单请求 。
当浏览器的请求方式是Head、Get或者Post,并且HTTP的头信息中不会超出以下字段
时,浏览器会将该请求定义为简单请求,否则就是非简单请求。当浏览器判断为简单请求后,浏览器会自动再请求报文头中加上Origin字段,表明此次请求来自的地址(协议+域名+端口)。然后服务器需要去判断是否接受这个来源的请求。如果允许服务器端返回的头部中需要有Access-Control-Allow-Origin,其值为请求时Origin字段的值或*(表示接受任意源的请求)。请求头中还会有Access-Control-Allow-Methods表示服务器允许的跨域请求的方式。Access-Control-Allow-Headers表示请求头中允许出现的字段.
2.2、 非简单请求 。
当浏览器判断为非简单请求后,会发送两次请求,首先浏览器会自动发送一个请求方式为options的请求,并在请求头中 。
服务器收到请求后,需要获取这三个请求头中的值,并进行判断,确认是否允许进行跨域。如果服务器返回的请求头中没有任何CORS相关的请求头信息,浏览器会认为不通过预检,也不会进行第二次请求.
服务器如果接受跨域并验证通过了options的请求,会返回Access-Control-Allow-Origin(表明允许跨域请求的源)、Access-Control-Allow-Methods(允许跨域请求的请求方式)、Access-Control-Allow-Headers(允许请求头中包含的额外字段)。然后浏览器才会发送真正的请求。 。
(第一次options请求) 。
(第二次请求) 。
2、服务端实现CORS 。
在.Net Core Web Api中使用很简单,首先安装包Microsoft.AspNet.WebApi.Cors,在StartUp中添加下面两句 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public
void
ConfigureServices(IServiceCollection services)
{
services.AddMvc();
//添加Cors,并配置CorsPolicy
services.AddCors(options => options.AddPolicy(
"CorsTest"
, p => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
}
public
void
Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
if
(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//注意UseCors()要在UseMvc()之前
app.UseCors(
"CorsTest"
);
app.UseMvc();
}
|
在使用的时候只需要在Controller或者Action中加上特性[EnableCors("CorsTest")] 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
[EnableCors(
"CorsTest"
)]
public
class
ValuesController : Controller
{
private
ILogger<ValuesController> _logger;
public
ValuesController(ILogger<ValuesController> logger)
{
_logger = logger;
}
[HttpGet]
public
IEnumerable<
string
> Get()
{
return
new
string
[] {
"value1"
,
"value2"
};
}
}
|
现在服务端已经配置好了,现在需要通过前端跨域请求 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<
html
>
<
head
>
测试
</
head
>
<
body
>
测试
</
body
>
</
html
>
<
script
src
=
"https://code.jquery.com/jquery-3.3.1.min.js"
></
script
>
<
script
type
=
"text/javascript"
>
$(function () {
$.ajax({
type: "get",
url: "http://localhost:7000/api/values",
beforeSend: function (request) {//在请求报文头中加入Authorization 目的是让请求为非简单请求
request.setRequestHeader("Authorization", "Bearer 071899A00D4D4C5B1C41A6B0211B9399");
},
success: function (result) {
alert(result);
}
}, "json");
});
</
script
>
|
测试结果如下图:
(options请求) 。
(第二次请求) 。
上面配置允许所有的地址请求这个接口,也可以单独配置某个地址.
1
2
3
|
services.AddCors(options => options.AddPolicy(
"CorsTest"
, p => p.WithOrigins(
"http://localhost:8089"
)
.AllowAnyHeader()
.AllowAnyMethod()));
|
3、解析Cors源码 。
打开CORS源码,主要的是CorsMiddleware、CorsOptions、CorsPolicy、CorsPolicyBuilder、CorsResult、CorsService这几个类.
services.AddCors(options => options.AddPolicy("CorsTest", p => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
IDictionary<string, CorsPolicy> PolicyMap
,一个项目可能有过个Cors配置,所以这个CorsOptions就是通过配置名称管理这些配置的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
public
async Task Invoke(HttpContext context)
{
//判断HTTP请求头是否有Origin,由此判断是不是跨域请求
if
(context.Request.Headers.ContainsKey(CorsConstants.Origin))
{
var corsPolicy = _policy ?? await _corsPolicyProvider?.GetPolicyAsync(context, _corsPolicyName);
if
(corsPolicy !=
null
)
{
var accessControlRequestMethod = context.Request.Headers[CorsConstants.AccessControlRequestMethod];
//如果是跨域请求 判断是不是第一次Options请求
if
(
string
.Equals(context.Request.Method,CorsConstants.PreflightHttpMethod,StringComparison.OrdinalIgnoreCase)
&&!StringValues.IsNullOrEmpty(accessControlRequestMethod))
{
//判断是否允许当前请求跨域,根据HttpContext的内容和Cors配置 得到CorsResult,然后将CorsResult的内容添加到请求头中(看下面详细解释)
ApplyCorsHeaders(context, corsPolicy);
context.Response.StatusCode = StatusCodes.Status204NoContent;
return
;
}
else
{
// 执行第二次非Options请求
context.Response.OnStarting(state =>
{
var (httpContext, policy) = (Tuple<HttpContext, CorsPolicy>)state;
try
{
ApplyCorsHeaders(httpContext, policy);
}
catch
(Exception exception)
{
_logger.FailedToSetCorsHeaders(exception);
}
return
Task.CompletedTask;
}, Tuple.Create(context, corsPolicy));
}
}
}
await _next(context);
}
private
void
ApplyCorsHeaders(HttpContext context, CorsPolicy corsPolicy)
{
//通过HTTP上下文请求的数据和Cors配置 得到CorsResult 如在第一次Options请求时,客户端发送了Origi:http://localhost:8089,Access-Control-Resquest-Methods:GET 服务器会返回Access-Control-Allow-Origin:http://localhost:8089,Access-Control-Allow-Methods:GET 服务器验证http://localhost:8089这个域名以GET请求方式是否允许跨域, 如果允许就将“http://localhost:8089”这个值存储到CorsResult的AllowedHeaders中 将"GET"存储到CorsResult的AllowedMethods中
var corsResult = _corsService.EvaluatePolicy(context, corsPolicy);
//将CorsResult中的值添加到相应头中的,返回到客户端
_corsService.ApplyResult(corsResult, context.Response);
}
|
相对来说Cors源码还是比较简单的,很容易看懂。可以自己写一个项目,然后挂上源码单步调试.
总结 。
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我的支持.
原文链接:https://www.cnblogs.com/MicroHeart/p/9298759.html 。
最后此篇关于.Net Core Cors中间件的深入讲解的文章就讲到这里了,如果你想了解更多关于.Net Core Cors中间件的深入讲解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
1、流程控制语句主要有if、ii...else、elseif(有时也可以写成else if)、switch四种。 PHP中语句格式为: if(条件满足) {执行语句} if(条件满足) {执行
目录 DFS初步概念 DFS例题-迷宫游戏 题目描述 输入输出格式 输入输出样例
This question两年前被问到,但它提到的资源要么不是很有帮助(恕我直言),要么链接不再有效。 必须有一些很好的教程才能理解 Phaser .我已经阅读了 javadoc,但我的眼睛呆滞了,因
This question两年前被问到,但它提到的资源要么不是很有帮助(恕我直言),要么链接不再有效。 必须有一些很好的教程才能理解 Phaser .我已经阅读了 javadoc,但我的眼睛呆滞了,因
这个正则出自这个网站 http://www.regexlab.com/zh/regref.htm 正向预搜索:"(?=xxxxx)","(?!xxxxx)"
chr(9)、chr(10)、chr(13)、chr(32)、chr(34) 所有关于 ASCII码的表格:[url]http://www.asciitable.com/[/url] chr(13)
我是一名优秀的程序员,十分优秀!