同源策略_如何支持跨域

欢迎大家阅读《朝夕Net社区技术专刊》

我们致力于.NetCore的推广和落地,为更好的帮助大家学习,方便分享干货,特创此刊!很高兴你能成为忠实读者,文末福利不要错过哦!

01

PART

CoreWebApi的调用

1.在Core MVC下建立WebApi—CrossDomainController控制器下的GetCrossDomainData api,如图1所示;启动后通过浏览器调用正常如图2;

图1

图2

2.那么试试Ajax调用试试呢?如图3,如果请求到,就把结果放到div 中去;那运行的时候,不仅没有获取到数据,而且还报错了如图4.

图3

图4

那么这里的问题就是浏览器的同源策略,引发的跨域问题;下面将把这个问题的根本缘由给大家做一下说明.

02

PART

浏览器同源策略

什么是同源策略?同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,请明确:他是浏览器的安全约定。所谓的同源,指的是协议,域名,端口相同。浏览器处于安全方面的考虑,只允许本域名下的接口交互,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源。

设想这样一种情况:A网站是一家银行,用户登录以后,又去浏览其他的网站,如果其他网站可以读取A网站的Cookie,会发生什么?很显然,如果Cookie包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是Cookie往往用来保存用于的登录状态,如果用户没有退出登录,其他网站就可以冒充用户为所欲为,因为浏览器同时还规定,提交表单不受同源策略的限制。由此可见,同源策略是必须的。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问;如图5。

图5

那么上面我们在调用的时候就是因为这个问题、Ajax的脚本,和Api非同源;Ajax请求Api的时候,违背了浏览器的这个约定,所以不能用;其实Ajax在请求的时候,是能够请求到Api的,Api也返回了数据;却因为浏览的同源要求,而报错了;下面给大家证明一下:运行Api:Api打断点:测试起来。。。如图6  、图7所示;

图6   

断点能进来

图7  

但是就是报错,浏览器限制了;不能用;

以上描述的就是浏览器的同源策略   在非同源的情况下使用脚本调用Api会报错的;这就是所谓的跨域问题。

03

PART

如何解决跨域问题?

首先来分析一下出这个问题的原因;是因为浏览器的约定而出现的;那么如果我不使用非同源的脚本来调用呢?是可以的;定义一个Api 模拟Http请求去请求这个非同源的Api;

第一步:定义定义Api 模拟http请求:

我这里是另外又建立了一个项目:模拟http请求;调用这个Api,让这个后台的Api再去调用非同源的Api-- GetCrossDomainData

第二步:运行起来:

包括运行GetCrossDomainDataApi所在的项目;命令启动:dotnet Zhaoxi.Core.WebApi.dll --urls="http://*:8004" -- ip="127.0.0.1" --port= 8004;监控的端口号为8004;

 

然后启动调用GetCrossDomainDataApi的项目:试试看;如图8 图9

图8

命令启动了;监控的是8004端口

图9

调用TestApi 方法;让其执行InvokeApi方法,去调用

GetCrossDomainDataApi;

执行结果:如图10

图10  

结果拿到了;避开了跨域问题;

那就是解决跨域问题的第一种策略:通过后台模拟Http请求,去调用Api,可以避开跨域问题;因为跨域是因为浏览器的同源引发的、不使用非同源的脚本去调用时Ok的;是不是很棒? 

这是第一种策略:我们再往下分析;看看刚刚在调用的时候,报的错是什么?

Access to XMLHttpRequest at 'http://localhost:64304/api/CrossDomain/GetCrossDomainData' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

其实这个提示也很明确哦:提示请求上下文不存在“Access-Control-Allow-origin” 头信息;那是不是加上这个头信息就Ok了呢?来试试看:请看下图11;仅仅只是加了一段代码。

图11

再来试试。。。来运行起来!还是命令启动:dotnet Zhaoxi.Core.WebApi.dll --urls="http://*:8004" --                          ip="127.0.0.1" --port= 8004 如图12

图12

Ajax调用:如图13  图14

图13

图14

这其实也是解决跨域的常用方法;就是在浏览器直接标记告诉调用者,Ok,我这个Api是允许你跨域访问的;仅此而已,是不是很简单?

不过如果用这种方法来支持跨域,难道在每个方法中都标记:HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");这句话吗?这很显然很不爽;

还记不记得,前面的文章中写了ActionFilter的使用?在这里是不是很适合?

OK 马上给你实现一个,定义个Filter,标记在方法上,如果需要所有Api 都跨域的话,全局注册即可;请看下图15  图16

图15

图16

测试结果如下:没毛病,完美解决问题;如图17

图17

以上也是解决跨域问题的常用策略;是通过在服务器指定当前Api允许跨域访问的方式;

下面我将继续给大家分享一种解决跨域问题的方式:其实在AspNetCore 中已经有支持跨域的Api;听我慢慢道来;

第一步:Nuget引入程序包:Microsoft.AspNetCore.Cors.dll

第二步:注册跨域服务:如图18

   

图18

 

第三步:use 跨域中间件:如图19

图19

 

测试结果如下:图20

图20

这里一共介绍了三种支持跨域的方式:

1.   通过后台模拟Http请求跨域

2.   服务器标记头信息 context.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");

3.   通过定义ActionFilter支持跨域其实和第二种原理一样;

4.   通过AspNetCore封装好的Cors来支持跨域;

下期预告

【朝夕Net社区技术专刊】

论ORM框架—EntityFrameworkCore

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值