
一,问题背景
基于Spring Cloud + gateway + nginx来搭建部署项目时,在gateway配置了跨域设置,如下:

但是会发现通过网关访问API时还是会有跨域问题。
这个时候聪明的你可能会想到在Nginx里也配置上跨域的设置, 如下:

但是还是一样的会有跨域问题。
然后又想起是不是业务代码里的Controller里也得加上CrossOrigin的配置,然后一通操作之后,还是有跨域问题,问题是响应头里有两个相同的*配置。
二,问题原因
1, Gateway里的配置和Nginx里配置不能重复,重复之后就会出现Duplicate的问题
2,Controller里加的跨域配置和Nginx里配置不能重复
3,Gateway里的配置不生效
三,解决方案
1,在Gateway中添加配置
完整如下:
spring:
main:
web-application-type: reactive
cloud:
loadbalancer:
cache:
ttl: 10
gateway:
discovery:
locator:
#开启从注册中心动态创建路由的功能,利用微服务名进行路由
enabled: true
#开启小写验证,默认feign根据服务名查找都是用的全大写
lowerCaseServiceId: true
filter:
remove-hop-by-hop:
headers:
# 以下是去掉网关默认的请求响应头
- trailer
- te
- keep-alive
- transfer-encoding
- upgrade
- proxy-authenticate
- connection
- proxy-authorization
- x-application-context
# 以下是去掉服务层面定义的跨域
- access-control-allow-credentials
- access-control-allow-headers
- access-control-allow-methods
- access-control-allow-origin
- access-control-max-age
- vary
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "*"
allowedHeaders: "*"
allowedMethods: "*"
maxAge: 3628800
2,使gateway的跨域配置生效
将 chain.filter(exchange); 替换成下面这个方法
private Mono<Void> getVoidMono(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.defer(() -> {
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(Collections.singletonList(kv.getValue().get(0))));
return chain.filter(exchange);
}));
}
Spring Cloud Gateway跨域问题及解决办法
8446

被折叠的 条评论
为什么被折叠?



