Skip to content

跨域问题


在微服务架构中,尤其是当前端与后端服务分离时,跨域问题是一个常见的问题。为了确保前端能成功地访问后端的接口,通常需要解决跨域问题(CORS:跨来源资源共享)。Spring Cloud Gateway 提供了跨域配置功能,能够通过配置网关来解决跨域问题。

跨域请求的配置包括设置 Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headers 等头信息,允许前端进行跨域请求。

可以使用全局过滤器(GlobalFilter)或者过滤工厂(FilterFactory)来解决跨域问题。


可以直接在 application.yml 中配置网关的跨域规则。

spring:
cloud:
gateway:
cors:
allowedOrigins: "*" # 允许所有的域名
allowedMethods: GET, POST, PUT, DELETE # 允许的HTTP方法
allowedHeaders: "*"
maxAge: 3600 # 预检请求的缓存时间,单位是秒
  • allowedOrigins:指定允许跨域请求的域名,* 表示允许所有域名跨域请求,可以设置成特定的域名如 http://example.com
  • allowedMethods:指定允许的 HTTP 方法,常见的如 GETPOSTPUTDELETE 等。
  • allowedHeaders:指定允许的请求头,* 表示允许所有请求头。
  • maxAge:指定预检请求(即 OPTIONS 请求)的缓存时间,单位是秒。

如果需要更细粒度的跨域控制,或者想要在全局范围内添加一些额外的跨域配置,可以使用 GlobalFilter 来实现。

@Component
public class CorsFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
HttpHeaders headers = exchange.getResponse().getHeaders();
headers.add("Access-Control-Allow-Origin", "*"); // 允许所有域名访问
headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); // 允许的请求方法
headers.add("Access-Control-Allow-Headers", "*"); // 允许所有请求头
headers.add("Access-Control-Max-Age", "3600"); // 预检请求缓存1小时
if ("OPTIONS".equalsIgnoreCase(exchange.getRequest().getMethodValue())) {
return exchange.getResponse().setComplete(); // 处理OPTIONS预检请求
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1; // 在其他过滤器之前执行
}
}
  • 这个 GlobalFilter 处理了跨域的 HTTP 头,并且支持 OPTIONS 请求。OPTIONS 请求是浏览器发起的跨域预检请求,用于检查服务器是否支持跨域操作。
  • Access-Control-Allow-Origin:允许的跨域域名。
  • Access-Control-Allow-Methods:允许的 HTTP 请求方法。
  • Access-Control-Allow-Headers:允许的请求头。

除了全局配置,还可以通过路由级别的配置来控制某些特定路由的跨域请求。可以在路由的配置中添加 CORS 配置。

spring:
cloud:
gateway:
routes:
- id: user-service
uri: http://localhost:8081
predicates:
- Path=/user/**
filters:
- name: AddRequestHeader
args:
name: X-Request-Id
value: 12345
- name: AddResponseHeader
args:
name: Access-Control-Allow-Origin
value: "*" # 允许所有域名访问

在这种方式下,CORS 配置只会作用于特定的路由。


  • 预检请求(OPTIONS:当前端发起跨域请求时,浏览器会首先发起一个预检请求(OPTIONS),用来询问服务器是否支持跨域。需要确保跨域过滤器能够正确响应 OPTIONS 请求。
  • 不同的跨域策略:如果希望更细粒度的控制跨域,可能需要根据请求头、来源等信息做更加个性化的配置。
  • 跨域支持范围Spring Cloud Gateway 支持跨域的 HTTP 方法、请求头和响应头等,但需要注意的是,实际生产环境中应该根据安全性需要,避免使用 * 来放开所有的跨域请求。