Spring Cloud 学习笔记(六)--Gateway 关于IE跨域的坑及实现
2020-01-14 11:57
721 查看
本人博客:https://cherishlife.com.cn/blog/29 有兴趣的朋友支持下,谢谢!
概述
在使用SpringCloud实现微服务时,经常会碰到前端页面访问多个二级域名的情况,跨域是首先要解决的问题。 解决这个问题,可以从两方面入手,一种方案是在微服务各自的业务模块中实现,即在SpringBoot层实现,另外一种方案就是在Gateway层实现。
本文主要介绍网关层的跨域实现。在本人实际项目中,发现一个针对IE浏览器的坑。
网上主流跨域实现
网上关于SpringCloud Gateway跨域的文章有不少,一般采用 WebFilter 实现。
[code]import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.gateway.discovery.DiscoveryClientRouteDefinitionLocator; import org.springframework.cloud.gateway.discovery.DiscoveryLocatorProperties; import org.springframework.cloud.gateway.route.RouteDefinitionLocator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.http.codec.support.DefaultServerCodecConfigurer; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.reactive.CorsUtils; import org.springframework.web.cors.reactive.CorsWebFilter; import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; import reactor.core.publisher.Mono; @Configuration public class CorsConfig { private static final String MAX_AGE = "18000L"; @Bean public WebFilter corsFilter() { return (ServerWebExchange ctx, WebFilterChain chain) -> { ServerHttpRequest request = ctx.getRequest(); if (CorsUtils.isCorsRequest(request)) { HttpHeaders requestHeaders = request.getHeaders(); ServerHttpResponse response = ctx.getResponse(); HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod(); HttpHeaders headers = response.getHeaders(); headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin()); headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders .getAccessControlRequestHeaders()); if(requestMethod != null){ headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name()); } headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"); headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*"); headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE); if (request.getMethod() == HttpMethod.OPTIONS) { response.setStatusCode(HttpStatus.OK); return Mono.empty(); } } return chain.filter(ctx); }; } @Bean public ServerCodecConfigurer serverCodecConfigurer() { return new DefaultServerCodecConfigurer(); } /** * 如果使用了注册中心(如:Eureka),进行控制则需要增加如下配置 */ @Bean public RouteDefinitionLocator discoveryClientRouteDefinitionLocator(DiscoveryClient discoveryClient, DiscoveryLocatorProperties properties) { return new DiscoveryClientRouteDefinitionLocator(discoveryClient, properties); } }
在实际应用中,发现对Chrome等其他浏览器没有问题,但是对IE浏览器却不支持。
兼容IE版本的跨域
改用 CorsWebFilter 实现。
[code]import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.gateway.discovery.DiscoveryClientRouteDefinitionLocator; import org.springframework.cloud.gateway.discovery.DiscoveryLocatorProperties; import org.springframework.cloud.gateway.route.RouteDefinitionLocator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.http.codec.support.DefaultServerCodecConfigurer; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.reactive.CorsUtils; import org.springframework.web.cors.reactive.CorsWebFilter; import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; import reactor.core.publisher.Mono; @Configuration public class CorsConfig { @Bean public CorsWebFilter corsWebFilter(CorsConfig corsConfig) { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration config = new CorsConfiguration(); // 允许cookies跨域 config.setAllowCredentials(true); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); config.setMaxAge(18000l); source.registerCorsConfiguration("/**", config); return new CorsWebFilter(source); } @Bean public ServerCodecConfigurer serverCodecConfigurer() { return new DefaultServerCodecConfigurer(); } /** * 如果使用了注册中心(如:Eureka),进行控制则需要增加如下配置 */ @Bean public RouteDefinitionLocator discoveryClientRouteDefinitionLocator(DiscoveryClient discoveryClient, DiscoveryLocatorProperties properties) { return new DiscoveryClientRouteDefinitionLocator(discoveryClient, properties); } }
至此能够完美兼容IE浏览器。
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- springCloud 学习笔记3 feign 实现客户端负载均衡
- 关于Spring Boot和Spring Cloud的学习笔记(更新中)
- springCloud 学习笔记2 ribbon 实现客户端负载均衡
- Spring Cloud微服务学习笔记之服务和数据的拆分与代码实现
- Spring学习笔记 关于spring 2.x中dependency-check标签与Spring3中的实现方式
- spring cloud 学习(二)关于 Eureka 的学习笔记
- ITCAST视频-Spring学习笔记(编码剖析@Resource注解的实现原理)
- 关于SQLServer2005的学习笔记——自定义分组的实现
- Thrift学习笔记(6)--Spring集成Thrift,实现服务端和客户端代理
- ITCAST视频-Spring学习笔记(使用Spring的注解方式实现AOP的细节)
- WebSocket学习笔记–IE,IOS,Android等设备的兼容性问题与代码实现
- TCP-IP学习笔记八:RPC(Netty和Spring)实现webServer框架
- spring cloud学习笔记-断路器
- 关于SQLServer2005的学习笔记——自定义分组的实现
- Spring学习笔记 关于Bean的初始化和清理-init和destroy方法
- Spring学习笔记(14)----使用CGLIB实现AOP功能
- Spring学习笔记(十二):关于Date的转换
- 关于springboot的学习笔记
- Zuul(SpringCloud学习笔记一)
- Spring Cloud 学习笔记