package com.ansel.CorsConfig;/**
* @author Ansel Zhong
* coding time
*/
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.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
@title reservationSys-test-v1
@author Ansel Zhong
@Date 2023/6/1
@Description
*/
@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);
}
}
});
}));
}
}
2) yaml文件
spring:
application:
name: service-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "*"
allowedHeaders: "*"
allowedMethods: "*"
default-filters:
- DedupeResponseHeader=Vary Access-Control-Allow-Origin Access-Control-Allow-Credentials, RETAIN_FIRST #一定要加这句话
routes: # 路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
- id: service-store #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: lb://service-store #匹配后提供服务的路由地址
predicates:
- Path=/admin/store/** # 断言,路径相匹配的进行路由
#filters: # 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
# - StripPrefix=1 # 转发之前去掉1层路径
- id: service-dict
uri: lb://service-dict
predicates:
- Path=/admin/dict/**
server:
port: 9001