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

Intro

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

什么是跨域

跨域:

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

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

同源策略:

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

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

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

这个就是同源策略的保护,如果浏览器对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,再请求一个带参网址实现跨域通信。

原生实现:

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

script.type = 'text/javascript';

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

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

document.head.appendChild(script);

// 回调执行函数

function handleCallback(res) {

alert(JSON.stringify(res));

}

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

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

jquery ajax

$.ajax({

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

type: 'get',

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

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

data: {}

});

后端 node.js 代码示例:

var querystring = require('querystring');

var http = require('http');

var server = http.createServer();

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

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

var fn = params.callback;

// jsonp返回设置

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

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

res.end();

});

server.listen('8080');

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

JSONP 只支持 GET 请求

代理

前端代理

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

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

后端代理

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

Ocelot 跨域配置

示例代码:

app.UseOcelot((ocelotBuilder, pipelineConfiguration) =>

{

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

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

ocelotBuilder.UseExceptionHandlerMiddleware();

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

if (pipelineConfiguration.PreErrorResponderMiddleware != null)

{

ocelotBuilder.Use(pipelineConfiguration.PreErrorResponderMiddleware);

}

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

ocelotBuilder.UseResponderMiddleware();

ocelotBuilder.UseDownstreamRouteFinderMiddleware();

ocelotBuilder.UseDownstreamRequestInitialiser();

ocelotBuilder.UseRequestIdMiddleware();

ocelotBuilder.UseMiddleware<ClaimsToHeadersMiddleware>();

ocelotBuilder.UseLoadBalancingMiddleware();

ocelotBuilder.UseDownstreamUrlCreatorMiddleware();

ocelotBuilder.UseOutputCacheMiddleware();

ocelotBuilder.UseMiddleware<HttpRequesterMiddleware>();

// cors headers

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

{

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

{

var allowedOrigins = Configuration.GetAppSetting("AllowedOrigins").SplitArray();

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

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

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

}

await next();

});

})

.Wait();

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

核心代码:

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

{

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

{

var allowedOrigins = Configuration.GetAppSetting("AllowedOrigins").SplitArray();

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

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

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

}

await next();

});

在 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 

html 跨域_常见跨域解决方案以及Ocelot 跨域配置相关推荐

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

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

  2. java 获取 word 窗体域_办公小技巧:巧用窗体域 控制Word文档修改区

    原标题:办公小技巧:巧用窗体域 控制Word文档修改区 有时我们发给别人的Word文档,仅仅需要对方修改其中的一小部分,比如房屋出租合同中的房屋承租人信息,采购清单中的数量信息等.这类文档中的其他信息 ...

  3. axios get怎么还会显示跨域_在Vue中如何使用axios跨域访问数据

    最近在项目中需要用到axios,所以就恶补一下这个axios到底是什么东东.越来它是vue-resource的替代品,官网也说了,以后都用axios, vue-resource不在维护.那么这个axi ...

  4. iframe 跨域_【梯云纵】搞定前端跨域

    韦陀掌法,难陀时间善恶:梯云纵,难纵过乱世纷扰. 现在开始写代码o(╯□╰)o 什么是跨域 1.跨域的定义 广义的跨域是指一个域下对的文档或者脚本试图去请求另外一个域下的资源. a链接.重定向.表单提 ...

  5. vue 前端设置允许跨域_[web]记一次sanic+vue跨域问题

    这两天在琢磨用sanic配合vue来写一个网站,果然马上就遇到问题了... Response to preflight request doesn't pass access control chec ...

  6. JAVA跨考_考研人的2019——一战跨考清华计算机的血泪史

    2019已经过去好多天了,看到大师傅们纷纷秀出了他们的年终总结,而每年都有积极参与的我,却到现在还迟迟没有写下这段时光,我无法原谅我自己,抱歉,俺太迟了. 考研人的 2019 终究是苦逼的一年,从确定 ...

  7. 跨域问题的前后端解决方案

    跨域问题是开发过程中一个比较常见的问题,无论你是前台开发,还是后台开发,可能都处理过这个问题.本文主要是介绍跨域常用的解决方案. 什么是跨域? 假设有这么一个场景,我有一个网站,在里面有一个显示商品的 ...

  8. gorilla websocket无法跨域_聊聊浏览器同源策略与跨域方案详解

    开发出高性能的 Web 应用固然重要,但安全问题也不容小觑.本文我们继续以 HTTP 为线索,展开来讲一讲浏览器安全相关的同源策略. 浏览器的同源策略(Same Origin Policy) 源(Or ...

  9. yii2 跨域请求配置_如何在SpringBoot应用中实现跨域访问资源和消息通信?

    允许跨域访问 CORS ( Cross Origin Resource Sharing,跨域资源共享)机制允许Web应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行.浏览器支持在API容器中 ...

最新文章

  1. 了解下SOAP Envelope 元素
  2. C/C++程序从编译到最终生成可执行文件的过程分析
  3. 恩施软件开发人员每月多少钱_恩施建个大棚多少钱搭建、养猪大棚价格
  4. 互联网1分钟 |1226
  5. java idea 模块_idea 多模块项目依赖父工程class找不到问题的方法
  6. 打印容器_3D打印:增材点阵结构在压力容器优化设计中的应用
  7. 常见的数据分析思维方式有哪些
  8. libkyototycoon.so.2: cannot open shared object file: No such file
  9. opencv图片保存0字节_openCV中IplImage的使用
  10. error: undefined reference to ‘_imp___ZN12QApplicationC1ERiPPci‘
  11. laravel8+jwt+邮箱注册验证
  12. 12_传智播客iOS视频教程_注释和函数的定义和调用
  13. IOl流的分类与使用
  14. 从MDK分散加载文件学习STM32启动流程
  15. 按位运算符与逻辑运算符的区别
  16. 【嵌入式学习】嵌入式开发的第一课
  17. CSDN去掉图片水印和调大小
  18. matlab凯塞窗设计,转载:用MATLAB设计FIR滤波器的方法解析
  19. 洛谷P1314 聪明的质检员(二分)
  20. Ubuntu 下安装极点五笔的方法

热门文章

  1. Tableau实战系列数据连接及数据准备
  2. 阿里妈妈:基于动态背包的多场景广告序列投放算法
  3. 深究 ElasticSearch 查询的秘密
  4. Zookeeper分布式集群部署
  5. tf.data.Dataset.from_tensor_slices() 详解
  6. 电商后台:实例解读订单系统
  7. encodeURIComponent的用法
  8. 关于VR技术和未来发展---转
  9. 简约之美Jodd-http--深入源码理解http协议
  10. Ambiguous mapping found. Cannot map 'xxxxController' bean method