我是年前搭建的微服务版,springBoot版本2.2.2.RELEASE,springCloud版本Hoxton.SR1。我的微服整体架构是eureka注册中心 + config配置中心 + gateway网关 + 服务若干。

一、先看看我的微服整体分支

data为vo、dto、util集合,每个服务都引入。

二、再上我gateway里的解决跨域Filter代码

import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
import org.springframework.cloud.gateway.config.GlobalCorsProperties;
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.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;

/**
 * 解决跨域
 * @author zwsky
 */
@Configuration
@ConditionalOnBean(GlobalCorsProperties.class)
public class GwCorsFilter {

    private static final String ALL = "*";
    private static final Long MAX_AGE = 18000L;

    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        // 允许cookies跨域
        config.setAllowCredentials(true);
        // #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
        config.addAllowedOrigin(ALL);
        // #允许访问的头信息,*表示全部
        config.addAllowedHeader(ALL);
        // 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
        config.setMaxAge(MAX_AGE);
        // 允许提交请求的方法类型,*表示全部允许
        config.addAllowedMethod(ALL);
        //配置前端js允许访问的自定义响应头
        //config.addExposedHeader("X-Token");
        config.addExposedHeader(ALL);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/*", config);

        return new CorsWebFilter(source);
    }

    /**
     *
     *如果使用了注册中心(如:Eureka),进行控制则需要增加如下配置
     */
    @Bean
    public RouteDefinitionLocator discoveryClientRouteDefinitionLocator(ReactiveDiscoveryClient discoveryClient, DiscoveryLocatorProperties properties) {
        return new DiscoveryClientRouteDefinitionLocator(discoveryClient,properties);
    }
}

PS:网上有的说路径应该是/**,我写成/**的时候gateway启动会报一个异常,说配置应该是/*。

这个解决跨域的Filter应该是没毛病的,期间参考官网与其他博友的技术分享,基本都是这样写的。也有说gateway设置了这个Filter,其他服务不能再使用extends WebMvcConfigurationSupport重写addCorsMappings的方法解决跨域

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**").allowedOrigins("*")
            .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
            .allowedHeaders("Cache-Control", "Content-Language", "Content-Type", "Expires", "Last-Modified", "Pragma", "x-requested-with", "X-Token");
}

我每个服务都检查了@Configuration注解的配置类,都没有这样代码片段了。

三、可能的原因

更改springBoot为2.2.6.RELEASE + springCloud为Hoxton.SR1后,唯一就是跨域Filter返回的CorsWebFilter的版本:

会变为spring-web:5.2.5RELEASE,我想应该还是agteway使用的WebFlux有关,下次看看源码。几天跟江南一点雨大佬哥也反馈了下,希望大佬哥能看到吧。

四、不看源码下的折腾

新版本网上的资源也少,之前只听说说过Spring Boot 2.2.4 发布!紧急修复Spring Cloud Hoxton.SR1,2.2.6的不兼容问题还没有大佬爆出。我这里简单的折腾是springBoot2.2.2后各个版本 + Hoxton.SR1/Hoxton.SR3,以及使用gateway的配置文件,然后跨域问题依然,爆出的一个错误也很奇葩:orgin “null”,Provisional headers are shown(F12调整,看header)

等一段时间,看看有没有大佬爆出吧,下面由时间我也看看spring-web:5.2.5RELEASE与spring-web:5.2.2RELEASE是不是有区别。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐