Spring Boot が @CrossOrigin を通じてクロスドメインを実現できることは誰もが知っています。ただ、Spring Cloudではそこまで細かい粒度でクロスドメインを制御したい場合は面倒なので、一般的にはrouting zuulで実装することになります。
zuul サービスの下に corsFilter を追加して、クロスドメインを実現します。これは実装が簡単です。コードは次のとおりです
@Configuration public 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 の場合、この構成はドメイン間で問題ありませんが、私の環境が https に切り替わると、奇妙な問題が発生します。私が遭遇した問題を説明してください。
フロントエンドサービスAとバックエンドサービスBが同じサーバー上にある場合、サービスAがサービスBを呼び出すと、サービスAは負荷分散を通じてサービスBに入ります。
service Aのクロスドメインリクエストは成功しますが、httpsを使用するとservice Aのクロスドメインリクエストは失敗します。
つまり、ポートが 443 の場合、クロスドメイン障害とみなされます。 ! 最初リクエストヘッダーを比較したところ、ExusedHeaderの「X-forwared-port、X-forwarded-host」が抜けているのかと思いましたが、追加してもやはり失敗しました。オンラインに接続することを急いでいたため、https リクエストがクロスドメインで失敗する原因について詳細なテストは実施しませんでした。 (したがって、私が書いたことに何か間違っていることに気づいた場合は、必ず私に通知して、失敗した理由を理解させてください! ありがとう!)
@Component public 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; } }
@Component public 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; } }
クロスドメイン ソリューション 1: CORS を使用して Cross-domain_html/css_WEB-ITnose を実装する
CORS を使用して WebApi Ajax クロスドメイン リクエストを実装する方法
以上がZuul は、corsFilter と ZuulFilter の継承の 2 つの方法で Cors クロスドメインを実装します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。