Spring Boot 中处理跨域资源

在 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。可以:

  1. 检查是否重复配置 :确保只在一个地方配置 CORS

  2. 使用 @Order 注解:指定配置的优先级

    @Configuration
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public class CorsConfig implements WebMvcConfigurer {
    // 配置
    }

  3. 检查 Nginx/Apache 配置:如果前端有代理服务器,确保代理服务器没有重复添加 CORS 头部

最简单的解决方案

对于快速测试,可以直接在控制器类上添加注解:

复制代码
@RestController
@CrossOrigin(origins = "*")
public class PrintController {
    // 你的代码
}

最佳实践建议

  1. 开发环境 :可以使用 *允许所有源

  2. 生产环境:应该指定具体的域名

  3. 如果有前端代理:可以考虑配置代理服务器处理 CORS

  4. 多个地方配置:确保不会在多个地方重复配置 CORS,否则会出现重复头部

选择最适合你项目需求的方案即可。通常方法1或方法2是最简单的解决方案。

相关推荐
Csvn3 分钟前
📊 SQL 入门 Day 22:视图与物化视图
后端·sql
Csvn6 分钟前
🐍 Day 4: Python 控制流 — 条件、循环与推导式的艺术
后端·python
吠品42 分钟前
Wine 在 Linux 上运行 Windows 软件完整指南
java·linux·服务器
2601_9537208244 分钟前
【计算机毕业设计】基于Vue与Spring Boot的高校兼职信息服务平台设计与实现
spring boot·后端·课程设计
亚历克斯神2 小时前
智能搜索系统的升级复盘——从 Elasticsearch 到混合检索的检索质量提升
java·spring·微服务
再吃一根胡萝卜2 小时前
用 Rust 写一个桌面悬浮图标:为什么它比 Python 更适合 AI 桌面工具?
后端
IT_陈寒2 小时前
Vue的computed属性把我坑惨了,原来我一直用错姿势
前端·人工智能·后端
金銀銅鐵3 小时前
[Java] 一个方法最多可以有多少个入参?
java·jvm
哭哭啼3 小时前
JAVA服务问题诊断
java·开发语言·jvm
evans在进步3 小时前
Spring Boot 核心机制详解:可执行 JAR、CORS、静态资源与配置绑定
spring boot·后端·jar