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是最简单的解决方案。

相关推荐
我命由我123453 小时前
Android Studio - Android Studio 自定义预览尺寸
android·java·ide·java-ee·android studio·android-studio·android runtime
mCell4 小时前
你以为短链接只是 Hash + 301/302?
后端·算法·架构
咖啡八杯4 小时前
GoF设计模式——迭代器模式
java·后端·设计模式·迭代器模式
AIGS0015 小时前
企业AI落地的关键认知:向量空间JBoltAI的本体语义平台
java·人工智能·人工智能ai大模型应用
KaMeidebaby5 小时前
卡梅德生物技术快报|抗体亲和力成熟工业化调控新机制:差异性浆细胞增殖工艺优化思路
java·开发语言·人工智能·算法·机器学习·架构·spark
醉城夜风~7 小时前
Java详解经典算法题:接雨水(三种实现方案+原理剖析)
java·开发语言·算法
数智化转型推荐官8 小时前
2026统一身份管理系统五大发展趋势解读
java·运维·微服务
看菜鸡互8 小时前
探索用 SlideML 让大模型生成 PPT 的实验方法
java·运维
IT_陈寒8 小时前
SpringBoot自动配置不是你以为的那样的智能
前端·人工智能·后端
ZhengEnCi10 小时前
S02-SpringBoot实体类新增字段对已有数据的影响及自动DDL同步机制详解
数据库·spring boot