常见跨域解决方案以及Ocelot 跨域配置

常见跨域解决方案以及Ocelot 跨域配置

Intro

我们在使用前后端分离的模式进行开发的时候,如果前端项目和api项目不是一个域名下往往会有跨域问题。今天来介绍一下我们在Ocelot网关配置的跨域。

什么是跨域

跨域:

浏览器对于javascript的同源策略的限制,例如a.cn下面的js不能调用b.cn中的js,对象或数据(因为a.cn和b.cn是不同域),所以跨域就出现了.

上面提到的,同域的概念又是什么呢??? 简单的解释就是相同域名,端口相同,协议相同

同源策略:

请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同.

比如:我在本地上的域名是study.cn,请求另外一个域名一段数据

640?wx_fmt=png

这个时候在浏览器上会报错:

640?wx_fmt=png

这个就是同源策略的保护,如果浏览器对javascript没有同源策略的保护,那么一些重要的机密网站将会很危险~

study.cn/json/jsonp/jsonp.html

当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。不同域之间相互请求资源,就算作“跨域”。

请求地址形式结果
http://study.cn/test/a.html同一域名,不同文件夹成功
http://study.cn/json/jsonp/jsonp.html同一域名,统一文件夹成功
http://a.study.cn/json/jsonp/jsonp.html不同域名,文件路径相同失败
http://study.cn:8080/json/jsonp/jsonp.html同一域名,不同端口失败
https://study.cn/json/jsonp/jsonp.html同一域名,不同协议失败

跨域几种常见的解决方案

解决跨域问题有几种常见的解决方案:

跨域资源共享(CORS)

通过在服务器端配置 CORS 策略即可,每门语言可能有不同的配置方式,但是从本质上来说,最终都是在需要配置跨域的资源的Response上增加允许跨域的响应头,以实现浏览器跨域资源访问,详细可以参考MDN上的这篇CORS介绍

JSONP

JSONP 方式实际上返回的是一个callbak,通常为了减轻web服务器的负载,我们把js、css,img等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许,基于此原理,我们可以通过动态创建script,再请求一个带参网址实现跨域通信。

原生实现:

  1. <script>

  2. var script = document.createElement('script');

  3. script.type = 'text/javascript';


  4. // 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数

  5. script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';

  6. document.head.appendChild(script);


  7. // 回调执行函数

  8. function handleCallback(res) {

  9. alert(JSON.stringify(res));

  10. }

  11. </script>

服务端返回如下(返回时即执行全局函数):

  1. handleCallback({"status": true, "user": "admin"})

jquery ajax

  1. $.ajax({

  2. url: 'http://www.domain2.com:8080/login',

  3. type: 'get',

  4. dataType: 'jsonp', // 请求方式为jsonp

  5. jsonpCallback: "handleCallback", // 自定义回调函数名

  6. data: {}

  7. });

后端 node.js 代码示例:

  1. var querystring = require('querystring');

  2. var http = require('http');

  3. var server = http.createServer();


  4. server.on('request', function(req, res) {

  5. var params = qs.parse(req.url.split('?')[1]);

  6. var fn = params.callback;


  7. // jsonp返回设置

  8. res.writeHead(200, { 'Content-Type': 'text/javascript' });

  9. res.write(fn + '(' + JSON.stringify(params) + ')');


  10. res.end();

  11. });


  12. server.listen('8080');

  13. console.log('Server is running at port 8080...');

JSONP 只支持 GET 请求

代理

前端代理

在现代化的前端开发的时候往往可以配置开发代理服务器,实际作用相当于做了一个请求转发,但实际请求的api地址是没有跨域问题的,然后由实际请求的api服务器转发请求到实际的存在跨域问题的api地址。

angular 配置开发代理可以参考 angular反向代理配置

后端代理

后端可以通过一个反向代理如(nginx),统一暴露一个服务地址,然后为所有的请求设置跨域配置,配置 CORS 响应头,Ocelot是ApiGateway,也可以算是api的反向代理,但不仅仅如此。

Ocelot 跨域配置

示例代码:

  1. app.UseOcelot((ocelotBuilder, pipelineConfiguration) =>

  2. {

  3. // This is registered to catch any global exceptions that are not handled

  4. // It also sets the Request Id if anything is set globally

  5. ocelotBuilder.UseExceptionHandlerMiddleware();

  6. // Allow the user to respond with absolutely anything they want.

  7. if (pipelineConfiguration.PreErrorResponderMiddleware != null)

  8. {

  9. ocelotBuilder.Use(pipelineConfiguration.PreErrorResponderMiddleware);

  10. }

  11. // This is registered first so it can catch any errors and issue an appropriate response

  12. ocelotBuilder.UseResponderMiddleware();

  13. ocelotBuilder.UseDownstreamRouteFinderMiddleware();

  14. ocelotBuilder.UseDownstreamRequestInitialiser();

  15. ocelotBuilder.UseRequestIdMiddleware();

  16. ocelotBuilder.UseMiddleware<ClaimsToHeadersMiddleware>();

  17. ocelotBuilder.UseLoadBalancingMiddleware();

  18. ocelotBuilder.UseDownstreamUrlCreatorMiddleware();

  19. ocelotBuilder.UseOutputCacheMiddleware();

  20. ocelotBuilder.UseMiddleware<HttpRequesterMiddleware>();

  21. // cors headers

  22. ocelotBuilder.Use(async (context, next) =>

  23. {

  24. if (!context.DownstreamResponse.Headers.Exists(h => h.Key == HeaderNames.AccessControlAllowOrigin))

  25. {

  26. var allowedOrigins = Configuration.GetAppSetting("AllowedOrigins").SplitArray<string>();

  27. context.DownstreamResponse.Headers.Add(new Header(HeaderNames.AccessControlAllowOrigin, allowedOrigins.Length == 0 ? new[] { "*" } : allowedOrigins));

  28. context.DownstreamResponse.Headers.Add(new Header(HeaderNames.AccessControlAllowHeaders, new[] { "*" }));

  29. context.DownstreamResponse.Headers.Add(new Header(HeaderNames.AccessControlRequestMethod, new[] { "*" }));

  30. }

  31. await next();

  32. });

  33. })

  34. .Wait();

这里扩展了一个 Ocelot pipeline 的配置,这样我们可以直接很方便的直接在 Startup 里配置 Ocelot 的请求管道。

核心代码:

  1. ocelotBuilder.Use(async (context, next) =>

  2. {

  3. if (!context.DownstreamResponse.Headers.Exists(h => h.Key == HeaderNames.AccessControlAllowOrigin))

  4. {

  5. var allowedOrigins = Configuration.GetAppSetting("AllowedOrigins").SplitArray<string>();

  6. context.DownstreamResponse.Headers.Add(new Header(HeaderNames.AccessControlAllowOrigin, allowedOrigins.Length == 0 ? new[] { "*" } : allowedOrigins));

  7. context.DownstreamResponse.Headers.Add(new Header(HeaderNames.AccessControlAllowHeaders, new[] { "*" }));

  8. context.DownstreamResponse.Headers.Add(new Header(HeaderNames.AccessControlRequestMethod, new[] { "*" }));

  9. }

  10. await next();

  11. });

在 HttpRequester 中间件后面添加这个中间件在响应中增加跨域请求头配置,这里先判断了一下下面的api有没有配置,如果已经配置则不再配置,使用下游api的跨域配置,这样一来,只需要在网关配置指定的允许跨域访问的源即使下游api没有设置跨域也是可以访问了

需要说明一下的是如果想要这样配置需要 Ocelot 13.2.0 以上的包,因为之前 HttpRequester 这个中间件没有调用下一个中间件,详见 https://github.com/ThreeMammals/Ocelot/pull/830

Reference

  • https://developer.mozilla.org/zh-CN/docs/Web/HTTP/AccesscontrolCORS

  • https://segmentfault.com/a/1190000011145364

  • https://github.com/ThreeMammals/Ocelot/pull/830

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 

640?wx_fmt=jpeg


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/315979.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解读大内老A的《.NET Core框架本质》

老A说的一句话让我很受启发&#xff0c;想要深入了解框架&#xff0c;你要把精力聚焦在架构设计的层面来思考问题。而透彻了解底层原理&#xff0c;最好的笨办法就是根据原理对框架核心进行重建或者说再造。看起来没有捷径&#xff0c;也是最快的捷径。相信很多读者已经看过老A…

Mono和.NET Core 从比翼双飞到合体

.NET 开源之路就是 Mono和.NET Core 从比翼双飞到合体&#xff1a;2001年12月-2002年2月。一个新的平台诞生了。与惠普、英特尔和其他公司一起, 创建了 ECMA-335 标准, 该标准定义了支持多种编程语言的公共语言基础结构&#xff0c;C# 和 Visual Basic. Net。 F # 于2007年晚些…

Skywalking部署常见问题以及注意事项

Skywalking部署常见问题以及注意事项IntroSkyWalking 创建与2015年&#xff0c;提供分布式追踪功能。从5.x开始&#xff0c;项目进化为一个完成功能的Application Performance Management系统。他被用于追踪、监控和诊断分布式系统&#xff0c;特别是使用微服务架构&#xff0c…

GitHub推出包管理服务,npm与Nuget全支持

GitHub 今天推出了一项名为 GitHub Package Registry 的新产品&#xff0c;它提供了软件包管理服务&#xff0c;开发者通过它可发布公共或私有软件包。官方介绍&#xff0c;GitHub Package Registry 完全集成在 GitHub 中&#xff0c;因此和 repo 一样&#xff0c;用户可以使用…

发布dotNetCore程序到Kubernetes

上一篇《Mac中搭建Kubernetes》介绍了怎样在Mac中搭建单节点的Kubernetes&#xff0c;本文将编写一个dotNetCore的示例程序&#xff0c;并发布到Kubernetes中。环境基本步骤创建dotnetCore示例项目&#xff1b;本地搭建私有registry&#xff0c;或者使用DockerHub&#xff0c;本…

[Cake] 2. dotnet 全局工具 cake

在上篇博客[Cake] 1. CI中的Cake中介绍了如何在CI中利用Cake来保持与CI/CD环境的解耦。当时dotnet 2.1还未正式发布&#xff0c;dotnet 还没有工具的支持&#xff0c;使得安装cake非常麻烦。不过随着 dotnet tool 的加入&#xff0c;这一问题得到了很好的解决。目前安装cake&am…

官博翻译 | .NET Core 即 .NET 的未来

点击上方蓝字关注“汪宇杰博客”文 / Scott Hunter译 / 汪宇杰我们在2014年11月推出了.NET Core 1.0。.NET Core 的目标是借鉴我们过去12年构建、发布和服务.NET Framework的经验去构建更好的产品。这些改进如&#xff1a;并行安装&#xff08;您可以安装新版本&#xff0c;而…

微软发布ML.NET 1.0,可一键添加机器学习模型

今天&#xff0c;我们很高兴宣布发布 ML.NET 1.0。ML.NET 是一个免费的、跨平台的开源机器学习框架&#xff0c;旨在将机器学习&#xff08;ML&#xff09;的强大功能引入.NET 应用程序。ML.NET GitHub&#xff1a;https://github.com/dotnet/machinelearning入门 http://dot.…

目前下载VS2017你可能会遇到这个坑

可能现在大伙都已经开始使用VS2019进行开发了。VS2019的下载使用也都很简单。由于工作需要&#xff0c;今天要在笔记本上安装VS2017,结果发现&#xff0c;VS2017的下载变得不是那么容易了&#xff0c;官方的下载方式也隐藏的很深&#xff0c;来来回回折腾了好一会才下载下来&am…

代码整洁之道(Clean Code)- 读书笔记

Sorry, 许久未更新文章了&#xff0c;主要因为刚刚换了一家新公司&#xff0c;忙于组建团队&#xff08;建设、招聘、流程、框架等&#xff09;与熟悉公司业务&#xff0c;还有领导给的其他工作等等&#xff0c;实在是没有时间更新了。最近在和团队分享Bob大叔的《Clean Code》…

微软Build 2019大会.NET课程视频汇总

点击上方蓝字关注“汪宇杰博客”5月6日至8日&#xff0c;微软在西雅图召开了Build 2019开发者大会。我们关注的.NET领域也迎来了许多激动人心的改进。本文汇总了Build 2019大会上关于.NET的已经公开的视频&#xff0c;欢迎大家观看学习&#xff01;// 注意&#xff1a;以下视频…

黑科技抢先尝 | Windows全新终端初体验(附代码Build全过程)

微软在几天前的build大会上展示了Windows Terminal的威力&#xff0c;由于官宣要在6月中旬才上Microsoft store&#xff0c;还有一个多月要等呢。好在代码已公布在 github, 于是决定自己 build 后体验一番。遇到不少坑&#xff0c;大概整理一下流程&#xff0c;分享给大家。如果…

aelf帮助C#工程师10分钟零门槛搭建DAPP私有链开发环境

aelf是一个可扩展的去中心化云计算区块链平台&#xff0c;支持高性能合约并行执行、原生多链数据交互、存储使用高性能分布式数据库。aelf整个系统可以在windows、osx及linux运行&#xff0c;团队在osx环境下开发&#xff0c;基于.net core DAPP开发1.安装.net core及protobufh…

Build 2019 上微软的开源动作有点不一样

微软今年举办的 Build 开发者大会可谓是抢足风头&#xff0c;大会第一天就放了不少大招&#xff1a;宣布新的命令行终端 Windows Terminal、Windows 10 的 Linux 子系统 WSL 2 将运行真正的 Linux 内核、跳过 .NET 4 宣布 .NET 5 的计划、宣布 Web 版本的 VS Code (Visual Stud…

P1437 [HNOI2004]敲砖块

P1437 [HNOI2004]敲砖块 题意&#xff1a; 在一个凹槽中放置了 n 层砖块、最上面的一层有 n 块砖&#xff0c;从上到下每层依次减少一块砖。每块砖都有一个分值&#xff0c;敲掉这块砖就能得到相应的分值&#xff0c;如下图所示&#xff1a; 14 15 4 3 2333 33 76 22 …

在kubernetes 集群内访问k8s API服务

所有的 kubernetes 集群中账户分为两类&#xff0c;Kubernetes 管理的 serviceaccount(服务账户) 和 useraccount&#xff08;用户账户&#xff09;。基于角色的访问控制&#xff08;“RBAC”&#xff09;使用“rbac.authorization.k8s.io”API 组来实现授权控制&#xff0c;允…

.NET Core之只是多看了你一眼

技术学习是一件系统性的事情&#xff0c;如果拒绝学习&#xff0c;那么自己就会落后以至于被替代。.NET也是一样&#xff0c;当开源、跨平台成为主流的时候&#xff0c;如果再故步自封&#xff0c;等待.NET的就是死路一条&#xff0c;幸好.NET Core问世了&#xff0c;社区反响积…

TOTP 介绍及基于 C# 的简单实现

TOTP 介绍及基于 C# 的简单实现IntroTOTP 是基于时间的一次性密码生成算法&#xff0c;它由 RFC 6238 定义。和基于事件的一次性密码生成算法不同 HOTP&#xff0c;TOTP 是基于时间的&#xff0c;它和 HOTP 具有如下关系&#xff1a;TOTP HOTP(K, T)HOTP(K,C) Truncate(HMAC-…

微软携手红帽,共筑开源新未来

官宣了&#xff0c;官宣了&#xff01;微软携手红帽正式推出重要力作Global Azure 公有云第一款联合管理的 OpenShift 产品&#xff0c;业界欢腾&#xff01;自此&#xff0c;微软在拥抱云计算开源之路上&#xff0c;多了一股强劲的推动力。5月初刚刚举办的全球 Red Hat Summit…

.NET Core 3.0之深入源码理解Startup的注册及运行

开发.NET Core应用&#xff0c;直接映入眼帘的就是Startup类和Program类&#xff0c;它们是.NET Core应用程序的起点。通过使用Startup&#xff0c;可以配置化处理所有向应用程序所做的请求的管道&#xff0c;同时也可以减少.NET应用程序对单一服务器的依赖性&#xff0c;使我们…