目录
一、问题
二、原因
二、解决方法
1、gateway设置允许跨域
2、手动写一个 CorsResponseHeaderFilter 的 GlobalFilter 去修改Response中的头
一、问题
前端代码访问后端代码时候会出现
Access to XMLHttpRequest at 'http://localhost:8080/user/logout' from origin 'http://localhost:8800' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.
这种报错,前端会显示不允许有多个’Access-Control-Allow-Origin’ CORS头
二、原因
仔细查看返回的响应头,里面包含了两份Access-Control-Allow-Origin头。
二、解决方法
1、gateway设置允许跨域
使用yml格式去设置允许跨域
gateway: globalcors: cors-configurations: '[/**]': allowedOrigins: "*" allowedHeaders: "*" allowedMethods: "*" default-filters: - DedupeResponseHeader=Vary Access-Control-Allow-Origin Access-Control-Allow-Credentials, RETAIN_FIRST
2、手动写一个 CorsResponseHeaderFilter 的 GlobalFilter 去修改Response中的头
@Component public class CorsResponseHeaderFilter implements GlobalFilter, Ordered { private static final Logger logger = LoggerFactory.getLogger(CorsResponseHeaderFilter.class); private static final String ANY = "*"; @Override public int getOrder() { // 指定此过滤器位于NettyWriteResponseFilter之后 // 即待处理完响应体后接着处理响应头 return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1; } @Override @SuppressWarnings("serial") 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) || kv.getKey().equals(HttpHeaders.VARY))) .forEach(kv -> { // Vary只需要去重即可 if(kv.getKey().equals(HttpHeaders.VARY)) kv.setValue(kv.getValue().stream().distinct().collect(Collectors.toList())); else{ List<String> value = new ArrayList<>(); if(kv.getValue().contains(ANY)){ //如果包含*,则取* value.add(ANY); kv.setValue(value); }else{ value.add(kv.getValue().get(0)); // 否则默认取第一个 kv.setValue(value); } } }); })); } }
引用:地址