政务网站建设 发言,军人运动会官方网站建设目标,国家基础设施建设网站,课堂网站开发常见跨域解决方案以及Ocelot 跨域配置Intro我们在使用前后端分离的模式进行开发的时候#xff0c;如果前端项目和api项目不是一个域名下往往会有跨域问题。今天来介绍一下我们在Ocelot网关配置的跨域。什么是跨域跨域:浏览器对于javascript的同源策略的限制,例如a.cn下面的js不… 常见跨域解决方案以及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介绍JSONPJSONP 方式实际上返回的是一个callbak通常为了减轻web服务器的负载我们把js、cssimg等静态资源分离到另一台独立域名的服务器上在html页面中再通过相应的标签从不同域名下加载静态资源而被浏览器允许基于此原理我们可以通过动态创建script再请求一个带参网址实现跨域通信。原生实现 script var script document.createElement(script); script.type text/javascript; // 传参一个回调函数名给后端方便后端返回时执行这个在前端定义的回调函数 script.src http://www.domain2.com:8080/login?useradmincallbackhandleCallback; document.head.appendChild(script); // 回调执行函数 function handleCallback(res) { alert(JSON.stringify(res)); } /script服务端返回如下返回时即执行全局函数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.UseMiddlewareClaimsToHeadersMiddleware(); ocelotBuilder.UseLoadBalancingMiddleware(); ocelotBuilder.UseDownstreamUrlCreatorMiddleware(); ocelotBuilder.UseOutputCacheMiddleware(); ocelotBuilder.UseMiddlewareHttpRequesterMiddleware(); // cors headers ocelotBuilder.Use(async (context, next) { if (!context.DownstreamResponse.Headers.Exists(h h.Key HeaderNames.AccessControlAllowOrigin)) { var allowedOrigins Configuration.GetAppSetting(AllowedOrigins).SplitArraystring(); 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).SplitArraystring(); 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/830Referencehttps://developer.mozilla.org/zh-CN/docs/Web/HTTP/AccesscontrolCORShttps://segmentfault.com/a/1190000011145364https://github.com/ThreeMammals/Ocelot/pull/830.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com