스프링 부트가 @CrossOrigin을 통해 크로스 도메인을 달성할 수 있다는 것은 누구나 알고 있습니다. 그러나 Spring Cloud에서는 이렇게 세밀하게 도메인 간을 제어하려는 경우 너무 번거롭기 때문에 일반적으로 라우팅 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이면 크로스 도메인 실패로 간주됩니다! ! 처음에 요청 헤더를 비교해서 ExposedHeader의 "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 상속이라는 두 가지 방법으로 Cors 교차 도메인을 구현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!