Spring Boot 解决跨域问题
在 Spring Boot 中解决跨域问题(CORS)主要有三种常用方式,下面详细说明每种实现方法:
方案一:全局配置(推荐)
在配置类中实现 WebMvcConfigurer
接口,统一配置所有接口的跨域规则:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") // 所有接口// Spring Boot 2.4+ 使用 allowedOriginPatterns.allowedOriginPatterns("*") // 允许的请求方法.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的请求头.allowedHeaders("*") // 是否允许发送Cookie.allowCredentials(true) // 预检请求缓存时间(秒).maxAge(3600); }
}
方案二:控制器注解配置
在单个控制器或方法上使用 @CrossOrigin
注解:
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
// 类级别配置(整个控制器生效)
@CrossOrigin(origins = "http://localhost:8080", allowCredentials = "true")
public class UserController {// 方法级别配置(覆盖类配置)@GetMapping("/users")@CrossOrigin(maxAge = 1800)public List<User> getUsers() {return userService.getAllUsers();}
}
方案三:过滤器配置(适合WebFlux或特殊需求)
创建自定义CORS过滤器:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;@Configuration
public class GlobalCorsConfig {@Beanpublic CorsFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();// 允许所有域名(生产环境建议指定具体域名)config.addAllowedOriginPattern("*");// 允许发送Cookieconfig.setAllowCredentials(true);// 允许所有请求头config.addAllowedHeader("*");// 允许所有方法config.addAllowedMethod("*");// 预检请求缓存时间config.setMaxAge(3600L);UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", config);return new CorsFilter(source);}
}
常见问题解决方案
-
Credentials 与 Origin 冲突问题
- 现象:前端携带 Cookie 时报错
- 解决:
// 正确配置 .allowCredentials(true) // 使用 allowedOriginPatterns 替代 allowedOrigins .allowedOriginPatterns("http://trusted-domain.com")
- 前端配合:
fetch(url, {credentials: 'include' // 必须 })
-
Spring Security 集成问题
在 Security 配置中启用 CORS:@Override protected void configure(HttpSecurity http) throws Exception {http.cors() // 启用 CORS.and()// ... 其他安全配置 }
-
OPTIONS 请求被拦截
- 确保未手动拦截 OPTIONS 方法
- 在 Security 配置中添加:
.antMatchers(HttpMethod.OPTIONS).permitAll()
-
多配置冲突
- 优先级:过滤器 > 全局配置 >
@CrossOrigin
- 建议整个项目统一使用一种配置方式
- 优先级:过滤器 > 全局配置 >
最佳实践建议
-
开发环境
使用全局配置 +allowedOriginPatterns("*")
快速开发 -
生产环境
.allowedOriginPatterns("https://your-domain.com","https://api.your-domain.com" )
-
安全加固
// 限制允许的请求头 .allowedHeaders("Content-Type", "X-Requested-With", "Authorization") // 暴露特定响应头 .exposedHeaders("Custom-Header")
重要提示:
- Spring Boot 2.4.x+ 必须使用
allowedOriginPatterns
替代旧版allowedOrigins
- 开启
allowCredentials(true)
时,禁止使用allowedOriginPatterns("*")
(浏览器安全限制),应指定具体域名