1.springboot升级版本以后websocket连接出现以下错误:
java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value “*” since that cannot be set on the “Access-Control-Allow-Origin” response header. To allow credentials to a set of origins, list them explicitly or consider using “allowedOriginPatterns” instead.
2.参考网上的博客,都是让我重写addCorsMappings方法,或者重新设置CoresFilter
网上的方法1:
>@ConfigurationpublicclassWebMvcConfigimplementsWebMvcConfigurer{>/**
> * 开启跨域
> */>@Override>publicvoidaddCorsMappings(CorsRegistry registry){>// 设置允许跨域的路由> registry.addMapping("/**")>// 设置允许跨域请求的域名>.allowedOriginPatterns("*")>// 是否允许证书(cookies)>.allowCredentials(true)>// 设置允许的方法>.allowedMethods("*")>// 跨域允许时间>.maxAge(3600);>}}
网上的方法2:
>@Bean>publicCorsFiltercorsFilter(){>// 1.配置CORS信息>CorsConfiguration config=newCorsConfiguration();>// 哪些原始域需要放行> config.addAllowedOriginPattern("*");// config.addAllowedOrigin("*");>// 哪些原始域需要放行(请求方式)> config.addAllowedMethod("*");>// 放行哪些原始域(头部信息)> config.addAllowedHeader("*");>// 是否发送Cookie信息> config.setAllowCredentials(true);>// 暴露哪些头部信息(因为跨域访问默认,所以不能获取到全部的头部信息)> config.addExposedHeader(HttpHeaders.LOCATION);> config.setExposedHeaders(Arrays.asList("JSESSIONID","SESSION","token",HttpHeaders.LOCATION,>HttpHeaders.ACCEPT,HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,>HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,>HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN,HttpHeaders.COOKIE,HttpHeaders.SET_COOKIE,>HttpHeaders.SET_COOKIE2));>// 2.添加映射路径实例>UrlBasedCorsConfigurationSource configSource=newUrlBasedCorsConfigurationSource();> configSource.registerCorsConfiguration("/**", config);>// 3.返回新的CorsFilter.>returnnewCorsFilter(configSource);>}
3.照着网上说的方法都试了一遍,还是报错,怀疑配置不生效,于是在网上找了一遍博客,照着源码debug,果然前面说的整改方法整改后的配置都没用到,连接websocket的时候实际用的是另外一个配置,所以还是报同样的错误
报错的源码,满足报错的条件,所以抛出异常
配置没生效,这里实际用的是另外一个allowedOrigins,在SockJsServiceRegistration里面设置
4.检查自己的SockJs连接的配置,发现了新大陆,将他改为setAllowedOriginPatterns即可
>@Configuration@EnableWebSocketMessageBrokerpublicclass>WebSocketAutoConfigimplementsWebSocketMessageBrokerConfigurer{>>@Override>publicvoidregisterStompEndpoints(StompEndpointRegistry registry){> registry.addEndpoint("/om-websocket")//开启/bullet端点>//.setAllowedOrigins("*") //允许跨域访问>.setAllowedOriginPatterns("*")//使用这个>.withSockJS();//使用sockJS>}>>@Override>publicvoidconfigureMessageBroker(MessageBrokerRegistry registry){>>//订阅Broker名称>//registry.enableSimpleBroker("/topic","/user");> registry.enableSimpleBroker("/websocket");>//全局使用的订阅前缀(客户端订阅路径上会体现出来)>//registry.setApplicationDestinationPrefixes("/app/");>//>//点对点使用的订阅前缀(客户端订阅路径上会体现出来),不设置的话,默认也是/user/>//registry.setUserDestinationPrefix("/user/");>}}
总结
这个乌龙让我调测了两天,主要还是过于相信网上的博客,认为照着网上的来配置问题就能解决,遇到问题首先应该检查自己的代码,而不是过于相信网上的博客,自己写的代码不一定和网上的一样,同时也应该自己去看源码,找到问题的根因
2021年11月25日补充,如果是结合SpringCloud Gateway使用,则gateway不需要配置任何跨域(网上的文章都说要配一个CorsWebFilter),否则会有以下报错,我用的SpringCloud版本是2020.0.4,原因待定位。。。。。
不要配这个,不要配这个,不要配这个!
@ConfigurationpublicclassCorsConfig{@BeanpublicCorsWebFiltercorsFilter(){CorsConfiguration config=newCorsConfiguration();
config.addAllowedMethod("*");// config.addAllowedOrigin("*");
config.addAllowedOriginPattern("*");
config.addAllowedHeader("*");
config.setAllowCredentials(true);UrlBasedCorsConfigurationSource source=newUrlBasedCorsConfigurationSource(newPathPatternParser());
source.registerCorsConfiguration("/**", config);returnnewCorsWebFilter(source);}}
报错信息: