您好,欢迎访问一九零五行业门户网

zuul实现Cors跨域的两种方式:corsFilter、继承ZuulFilter

大家都知道spring boot 可以通过@crossorigin实现跨域。但是在spring cloud 里,如果要粒度那么细的去控制跨域,这个就太繁琐了,所以一般来说,会在路由zuul里实现。
第一种方式:corsfilter在zuul服务下添加一个corsfilter实现跨域,实现起来方便。代码如下
@configurationpublic class gatewaycorsconfig { @bean public filterregistrationbean corsfilter() { final urlbasedcorsconfigurationsource source = new urlbasedcorsconfigurationsource(); final corsconfiguration config = new corsconfiguration(); config.setallowcredentials(true); config.addallowedorigin("*"); config.addallowedheader("*"); config.addallowedmethod("*"); //这个请求头在https中会出现,但是有点问题,下面我会说 //config.addexposedheader("x-forwared-port, x-forwarded-host"); source.registercorsconfiguration("/**", config); filterregistrationbean bean = new filterregistrationbean(new corsfilter(source)); bean.setorder(ordered.highest_precedence); return bean; }}
经过测试,这样的配置在http的情况下跨域是ok的,但是当我的环境切换的https的情况下就发生了奇怪的问题。说明一下我遇到的问题。
前端 服务a 和 后端服务b 在同一台服务器上,服务a 调用 服务b 时,服务a通过负载均衡进入服务b时:
http时,服务a的请求跨域成功,https时,服务a的请求跨域失败。
也就是端口为443的时候,会被认为跨域失败!!
我一开始对比了请求头,以为是少了exposedheader的"x-forwared-port, x-forwarded-host",但是添加后,还是失败。因为急着上线,所以我没有去深入测试到底什么原因引起的https请求跨域失败。(所以如果大家发现我哪里写的不对,请务必通知我,让我也明白为什么失败!谢谢!)
第二种方式:继承zuulfilter因为第一种方式在https下失败后,我尝试了用zuulfilter实现cors的方式
一共需要两个filiter:一个pre, 一个post
pre-filter:
@componentpublic class firstfilter extends zuulfilter { private logger logger = loggerfactory.getlogger(firstfilter.class); @override public string filtertype() { /* pre:可以在请求被路由之前调用 route:在路由请求时候被调用 post:在route和error过滤器之后被调用 error:处理请求时发生错误时被调用 * */ // 前置过滤器 return filterconstants.pre_type; } @override public int filterorder() { //// 优先级为0,数字越大,优先级越低 return 0; } @override public boolean shouldfilter() { requestcontext ctx = requestcontext.getcurrentcontext(); httpservletrequest request = ctx.getrequest(); //只过滤options 请求 if(request.getmethod().equals(requestmethod.options.name())){ return true; } return false; } @override public object run() { logger.debug("*****************firstfilter run start*****************"); requestcontext ctx = requestcontext.getcurrentcontext(); httpservletresponse response = ctx.getresponse(); httpservletrequest request = ctx.getrequest(); response.setheader("access-control-allow-origin",request.getheader("origin")); response.setheader("access-control-allow-credentials","true"); response.setheader("access-control-allow-headers","authorization, content-type"); response.setheader("access-control-allow-methods","post,get"); response.setheader("access-control-expose-headers","x-forwared-port, x-forwarded-host"); response.setheader("vary","origin,access-control-request-method,access-control-request-headers"); //不再路由 ctx.setsendzuulresponse(false); ctx.setresponsestatuscode(200); logger.debug("*****************firstfilter run end*****************"); return null; }}
pre-filter 用来处理预处理options请求,当发现是options请求的时候,给出跨域响应头,并且不对其进行zuul路由,直接返回成功(200), 给前端服务允许跨域
post-filter :
@componentpublic class postfilter extends zuulfilter { private logger logger = loggerfactory.getlogger(postfilter.class); @override public string filtertype() { /* pre:可以在请求被路由之前调用 route:在路由请求时候被调用 post:在route和error过滤器之后被调用 error:处理请求时发生错误时被调用 * */ // 前置过滤器 return filterconstants.post_type; } @override public int filterorder() { //// 优先级为0,数字越大,优先级越低 return 2; } @override public boolean shouldfilter() { requestcontext ctx = requestcontext.getcurrentcontext(); httpservletrequest request = ctx.getrequest(); //过滤各种post请求 if(request.getmethod().equals(requestmethod.options.name())){ return false; } return true; } @override public object run() { logger.debug("*****************postfilter run start*****************"); requestcontext ctx = requestcontext.getcurrentcontext(); httpservletresponse response = ctx.getresponse(); httpservletrequest request = ctx.getrequest(); response.setheader("access-control-allow-origin",request.getheader("origin")); response.setheader("access-control-allow-credentials","true"); response.setheader("access-control-expose-headers","x-forwared-port, x-forwarded-host"); response.setheader("vary","origin,access-control-request-method,access-control-request-headers"); //允许继续路由 ctx.setsendzuulresponse(true); ctx.setresponsestatuscode(200); logger.debug("*****************postfilter run end*****************"); return null; }}
post-filter 用来处理 预处理options以外的请求,对于正常的请求,不但要给出跨域请求头,还需要允许请求进行路由(否则你的请求到这儿就结束啦),然后返回状态码200。(emmmm……这里要不要返回200,我觉得可能还要想一想……)
按照以上方式配置的话,方法一出现的问题,就得到了解决。服务a能够正常请求服务b了
虽然是正常实现了需求,但是感觉还是存在很多疑惑,希望大家看到的话,能给我指出不足。一起讨论!
相关文章:
跨域解决方案一:使用cors实现跨域_html/css_web-itnose
用cors实现webapi ajax跨域请求的方法
请求跨域解决方法cors
以上就是zuul实现cors跨域的两种方式:corsfilter、继承zuulfilter的详细内容。
其它类似信息

推荐信息