使用Spring cloud gateway 创建的一个网关服务后,在application.yml中配置跨域,如下:
spring:
cloud:
gateway:
routes:
- id: xxxxx
uri: https://www.xxxxx.com
predicates:
- Path=/xxx/**
filters:
- StripPrefix=1
globalcors:
# 解决OPTIONS请求被拦截问题
add-to-simple-url-handler-mapping: true
cors-configurations:
'[/**]':
# 允许跨域的请求源(Spring Boot 2.4+版本使用此配置)
allowedOriginPatterns: ["*"]
allowedMethods: ["*"]
allowedHeaders: ["*"]
# 是否允许携带cookie
allowCredentials: true
# 跨域检测的有效期,单位秒
maxAge: 3600
注意事项:
- 凭证与通配符限制 :当
allow-credentials设置为true时,allowed-origins 不能设置为 "*",必须指定具体域名 - options请求处理 :必须配置
add-to-simple-url-handler-mapping: true来确保预检请求不被拦截 - 版本兼容性 :Spring Boot 2.4及以上版本推荐使用
allowed-origin-patterns替代allowed-origins
Spring Cloud Gateway配置跨域后确实会在响应头中添加跨域相关配置。
在一些微服务场景下,比如调用第三方服务的时候,第三方服务有可能也配置了跨域配置,如果这时,我们网关服务也配置了跨域配置,就会在响应头中出现多个Access-Control-Allow-Origin 响应头,从而导致跨域配置失效。
为避免出现多个Access-Control-Allow-Origin响应头,需要使用DedupeResponseHeader 过滤器来去重响应头
DedupeResponseHeader过滤器的作用:
- 用于去除重复的响应头
- 可指定多个需要去重的响应头名称,用空格分隔
- 支持多种去重策略,如
RETAIN_FIRST(保留第一个)、RETAIN_LAST(保留最后一个)等
完整的配置如下:
spring:
cloud:
gateway:
routes:
- id: xxxxx
uri: https://www.xxxxx.com
predicates:
- Path=/xxx/**
filters:
- StripPrefix=1
globalcors:
# 解决OPTIONS请求被拦截问题
add-to-simple-url-handler-mapping: true
cors-configurations:
'[/**]':
# 允许跨域的请求源(Spring Boot 2.4+版本使用此配置)
allowedOriginPatterns: ["*"]
allowedMethods: ["*"]
allowedHeaders: ["*"]
# 是否允许携带cookie
allowCredentials: true
# 跨域检测的有效期,单位秒
maxAge: 3600
default-filters:
# 使用RETAIN_FIRST策略确保保留最先设置的响应头值,也就是网关的跨域配置
- DedupeResponseHeader=Vary Access-Control-Allow-Origin Access-Control-Allow-Credentials, RETAIN_FIRST