1. 网关明明设置了一次,为什么却说重复跨域呢?
原因是网关跨域设置是前端端口号与网关端口号的跨域,而使用网关的话会再次转发调用其他网站,所以会出现明明只设置了一次,并且将controller的跨域注解也注释了,却说重复跨域的问题了,而不是网上说的什么nginx多次配置跨域请求了。
注意:跨域只设置一次的时候请检查nginx的跨域是否关闭,controller的@CrossOrigin
是否关闭,以保证咱们配置的时候只有一个跨域配置,
2. 解决办法:
2.1:配置网关的跨域配置
package com.laoyang.config;
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;
@Configuration
public class CorsConfig {
//解决跨域
@Bean
public CorsWebFilter corsWebFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedMethod("*");
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**",config);
return new CorsWebFilter(source);
}
}
2.2 还需要去除重复的跨域设置过滤器:
package com.laoyang.filter;
/**
* @author:Kevin
* @create: 2022-10-14 22:45
* @Description:
*/
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Arrays;
/**
* 重复跨域,去重
*/
@Component("corsResponseHeaderFilter")
public class ResponseCorsHeaderFilter implements GlobalFilter, Ordered{
private static final Logger logger = LoggerFactory.getLogger(ResponseCorsHeaderFilter.class);
@Override
public int getOrder() {
// 指定此过滤器位于NettyWriteResponseFilter之后
// 即待处理完响应体后接着处理响应头
return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1000;
}
/**
* Process the Web request and (optionally) delegate to the next {@code WebFilter}
* through the given {@link GatewayFilterChain}.
*
* @param exchange the current server exchange
* @param chain provides a way to delegate to the next filter
* @return {@code Mono<Void>} to indicate when request processing is complete
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
exchange.getResponse().getHeaders().entrySet().stream()
.filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
.filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)
|| kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)))
.forEach(kv -> {
kv.setValue(Arrays.asList(kv.getValue().get(1)));
});
}));
}
}