在 Spring Boot 中处理跨域资源共享(CORS)问题,有多种解决方案。以下是几种常见的方法:
方法1:在控制器或方法上添加 @CrossOrigin 注解(推荐)
@RestController
@CrossOrigin(origins = "*") // 允许所有源
// 或者指定特定源:@CrossOrigin(origins = "http://localhost:3000")
public class PrintController {
@PostMapping(value = "/v1/multiples", produces = { "application/json" })
@ResponseStatus(HttpStatus.CREATED)
@CrossOrigin(origins = "*") // 也可以加在方法级别
public EntityModel<Map<String, Object>> multiples() {
return EntityModel.of(overallMap);
}
}
方法2:全局配置(推荐)
创建全局 CORS 配置类:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*") // 允许所有源
// 或者指定特定源:.allowedOrigins("http://localhost:3000", "http://example.com")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(false) // 如果使用 allowCredentials(true),allowedOrigins 不能为 "*"
.maxAge(3600);
}
}
方法3:使用 CorsFilter 过滤器
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
// 设置允许跨域请求的域名
config.addAllowedOrigin("*");
// 或者指定特定域名
// config.addAllowedOrigin("http://localhost:3000");
// 允许跨域请求头
config.addAllowedHeader("*");
// 允许跨域请求方法
config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
config.addAllowedMethod("PUT");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("OPTIONS");
// 暴露哪些头部信息
config.addExposedHeader("Authorization");
// 允许凭证
config.setAllowCredentials(true);
// 预检请求的有效期,单位为秒
config.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
方法4:在 Spring Security 中配置 CORS
如果使用了 Spring Security:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().and() // 启用 CORS
.csrf().disable() // 如果是 API 接口,通常禁用 CSRF
.authorizeRequests()
.antMatchers("/v1/multiples").permitAll()
.anyRequest().authenticated();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.setExposedHeaders(Arrays.asList("Authorization"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
方法5:如果遇到多个 CORS 头部问题
如果出现两个 access-control-allow-origin头部,通常是因为多个地方都配置了 CORS。可以:
-
检查是否重复配置 :确保只在一个地方配置 CORS
-
使用 @Order 注解:指定配置的优先级
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsConfig implements WebMvcConfigurer {
// 配置
} -
检查 Nginx/Apache 配置:如果前端有代理服务器,确保代理服务器没有重复添加 CORS 头部
最简单的解决方案
对于快速测试,可以直接在控制器类上添加注解:
@RestController
@CrossOrigin(origins = "*")
public class PrintController {
// 你的代码
}
最佳实践建议
-
开发环境 :可以使用
*允许所有源 -
生产环境:应该指定具体的域名
-
如果有前端代理:可以考虑配置代理服务器处理 CORS
-
多个地方配置:确保不会在多个地方重复配置 CORS,否则会出现重复头部
选择最适合你项目需求的方案即可。通常方法1或方法2是最简单的解决方案。