今天前端突然说接口不支持跨域了,马上排查了一番,原因是之前接口一直提供给 App 使用,所以没有遇到浏览器跨域限制。
解决方案就是在网关处新增配置类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.util.pattern.PathPatternParser;

@Configuration
public class CorsConfig {

/**
* 允许跨域请求
*
* @return bean
*/
@Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();

// 允许 Cookie、Authorization 等凭证跨域。
// 如果不需要携带凭证,可以设置为 false,并按需使用 *。
config.setAllowCredentials(true);

// allowCredentials=true 时不能使用 allowedOrigins("*")。
// 生产环境推荐配置明确域名;如果确实需要匹配一组域名,使用 allowedOriginPattern。
config.addAllowedOrigin("https://admin.example.com");
config.addAllowedOriginPattern("https://*.example.com");

// 允许访问的头信息,* 表示全部
config.addAllowedHeader("*");
// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
config.setMaxAge(18000L);
// 允许提交请求的方法类型
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");

org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource source =
new org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", config);

return new CorsWebFilter(source);
}
}

注意:网关加上跨域之后,在各个微服务对应的 Controller 上通常就不需要再加 @CrossOrigin。生产环境不要无差别放开所有来源,优先把来源域名收敛到前端实际使用的域名。