SpringCloud版本Greenwich.RELEASE
Springboot版本2.1.4.RELEASE
gateway中全局的跨域問題解決兩種方式优训,一種是創(chuàng)建配置類不推薦,如有需要可以自己查詢相關(guān)資料;另一種是使用配置文件泰讽,相對簡單甜紫,如下:
spring:
cloud:
gateway:
# gateway的全局跨域請求配置
globalcors:
corsConfigurations:
'[/**]':
allowedHeaders: "*"
allowedOrigins: "*"
allowCredentials: true
allowedMethods: "*"
上述屬性值可以根據(jù)自己的需要配置,"*"表示所有雄嚣。
正常情況下基于以上配置即可晒屎,但是由于目前的項目的下游微服務(wù)也配置了可以跨域的相關(guān)配置,這就導(dǎo)致返回的ResponseHeader中有多重屬性缓升,這個多重屬性瀏覽器是不認的鼓鲁。所以基于此的處理方法,把下游的所有配置都取消港谊,但是下游服務(wù)數(shù)量又太多骇吭,所以通過查詢找到了以下的方案,參考https://github.com/spring-cloud/spring-cloud-gateway/issues/728:
spring:
cloud:
gateway:
# gateway的全局跨域請求配置
globalcors:
corsConfigurations:
'[/**]':
allowedHeaders: "*"
allowedOrigins: "*"
allowCredentials: true
allowedMethods: "*"
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Origin Access-Control-Allow-Credentials Vary, RETAIN_UNIQUE
在配置文件中添加上面的過濾器歧寺,這個過濾器的作用是剔除重復(fù)的響應(yīng)頭燥狰。gateway的內(nèi)置的過濾器可以參考這篇文章:https://blog.csdn.net/tuyong1972873004/article/details/107123254。
內(nèi)置的過濾器有很多斜筐,可以根據(jù)自己的實際需求去配置龙致。
正常情況下以上配置就可以解決上述的問題,但是發(fā)現(xiàn)后臺報錯顷链,錯誤信息提示無法找到DedupeResponseHeaderGateWayFilter目代。后來查詢資料才發(fā)現(xiàn),這個過濾器是GreenwichSR2版本提供的新特性,當(dāng)前的springcloud版本太低榛了。所以最后沒有辦法在讶,只能手動實現(xiàn)一個和DedupeResponseHeaderGateWayFilter功能相同的過濾器。代碼如下:
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;
@Component("corsResponseHeaderFilter")
public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(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(new ArrayList<String>() {{
add(kv.getValue().get(0));
}});
});
return chain.filter(exchange);
}));
}
@Override
public int getOrder() {
// 指定此過濾器位于NettyWriteResponseFilter之后
// 即待處理完響應(yīng)體后接著處理響應(yīng)頭
return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;
}
}
加上以上配置類后霜大,問題解決构哺。