题目详细答案

使用 @CrossOrigin 注解

@CrossOrigin 是 Spring Framework 提供的一个注解,用于在控制器方法或整个控制器上指定允许的跨域请求。这个注解可以在方法级别或类级别使用。

@RestController
public class MyController {

    @GetMapping("/api/data")
    @CrossOrigin(origins = "http://localhost:3000", maxAge = 3600)
    public List<Data> getData() {
        // 返回数据
    }
}

@CrossOrigin 注解指定了来自 http://localhost:3000 的跨域请求是被允许的,并且设置了预检请求的缓存时间为 3600 秒(1 小时)。

@RestController
@CrossOrigin(origins = "http://localhost:3000", maxAge = 3600)
public class MyController {

    @GetMapping("/api/data")
    public List<Data> getData() {
        // 返回数据
    }
}

所有在 MyController 中的方法都将允许来自 http://localhost:3000 的跨域请求。

使用 WebMvcConfigurer 接口

如果你需要在全局范围内配置 CORS 策略,可以实现 WebMvcConfigurer 接口并重写 addCorsMappings 方法。

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
               .allowedOrigins("http://localhost:3000")
               .maxAge(3600);
    }
}

创建一个 CorsConfig 类,实现了 WebMvcConfigurer 接口,并在 addCorsMappings 方法中添加了一个全局的 CORS 配置,允许来自 http://localhost:3000 的跨域请求。

Spring MVC 跨域(CORS)配置详解

跨域资源共享(CORS)概述

跨域资源共享(Cross-Origin Resource Sharing, CORS)是一种机制,它使用额外的HTTP头来告诉浏览器让运行在一个源(domain)上的Web应用被准许访问来自不同源服务器上的指定资源。

两种配置方式对比

特性

@CrossOrigin 注解

WebMvcConfigurer 接口

作用范围

方法级/类级

全局配置

灵活性

细粒度控制

统一管理

适用场景

特定端点需要特殊CORS规则

整个应用使用相同的CORS策略

维护性

分散在各处

集中管理

优先级

更具体(方法>类>全局)

基础配置

@CrossOrigin 注解详解

基本用法

@RestController
@RequestMapping("/api")
public class MyController {
    
    // 方法级别配置
    @GetMapping("/data")
    @CrossOrigin(origins = "http://localhost:3000")
    public ResponseEntity<List<Data>> getData() {
        // 业务逻辑
    }
    
    // 类级别配置
    @CrossOrigin(origins = "https://example.com", maxAge = 1800)
    @GetMapping("/users")
    public ResponseEntity<List<User>> getUsers() {
        // 业务逻辑
    }
}

注解参数说明

参数名

类型

说明

origins

String[]

允许的源列表,默认"*"

allowedHeaders

String[]

允许的请求头,默认"*"

exposedHeaders

String[]

暴露给客户端的响应头

methods

RequestMethod[]

允许的HTTP方法,默认与注解的方法匹配

allowCredentials

boolean

是否允许发送凭据(cookies等),默认false

maxAge

long

预检请求缓存时间(秒),默认1800

高级用法示例

// 允许多个源
@CrossOrigin(origins = {"http://localhost:3000", "https://example.com"})

// 允许所有源但限制方法
@CrossOrigin(origins = "*", methods = {RequestMethod.GET, RequestMethod.POST})

// 允许凭据和自定义头
@CrossOrigin(
    origins = "https://app.example.com",
    allowedHeaders = {"Authorization", "Content-Type"},
    exposedHeaders = {"X-Custom-Header"},
    allowCredentials = "true",
    maxAge = 3600
)

WebMvcConfigurer 全局配置详解

基本配置

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
               .allowedOrigins("http://localhost:3000", "https://example.com")
               .allowedMethods("GET", "POST", "PUT", "DELETE")
               .allowCredentials(true)
               .maxAge(3600);
    }
}

配置选项说明

方法名

说明

addMapping(String)

设置CORS映射路径,支持Ant风格路径模式

allowedOrigins

设置允许的来源,可以多个

allowedMethods

设置允许的HTTP方法

allowedHeaders

设置允许的请求头

exposedHeaders

设置暴露给客户端的响应头

allowCredentials

设置是否允许凭据

maxAge

设置预检请求缓存时间

多路径不同规则配置

@Override
public void addCorsMappings(CorsRegistry registry) {
    // API路径配置
    registry.addMapping("/api/**")
           .allowedOrigins("https://api-consumer.com")
           .allowedMethods("GET", "POST");
    
    // 管理后台配置
    registry.addMapping("/admin/**")
           .allowedOrigins("https://admin.example.com")
           .allowedMethods("*")
           .allowCredentials(true);
    
    // 公共API配置
    registry.addMapping("/public/**")
           .allowedOrigins("*")
           .allowedMethods("GET");
}

最佳实践建议

  1. 安全考虑
    • 避免在生产环境使用allowedOrigins("*")
    • 明确指定允许的来源列表
    • 对于敏感操作,设置allowCredentials(false)
  1. 性能优化
    • 合理设置maxAge减少预检请求
    • 按需暴露头信息,避免不必要的exposedHeaders
  1. 混合使用策略
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 全局基础配置
        registry.addMapping("/**")
               .allowedOrigins("https://main-site.com")
               .maxAge(1800);
    }
}

@RestController
@CrossOrigin(origins = "https://partner-site.com") // 特定控制器覆盖配置
@RequestMapping("/partner-api")
public class PartnerApiController {
    // ...
}
  1. 常见问题解决
    • 配置不生效:检查配置类是否被正确扫描,注解是否放在正确位置
    • 预检请求失败:确保OPTIONS方法被允许,maxAge设置合理
    • 凭据问题:当使用allowCredentials(true)时,不能使用allowedOrigins("*")
  1. Spring Security集成
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and() // 启用Spring Security的CORS支持
            .csrf().disable()
            // 其他安全配置...
    }
    
    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("https://trusted.com"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

实际应用场景

  1. 前后端分离项目
@CrossOrigin(origins = "http://localhost:8080")
@RestController
public class FrontendApiController {
    // 前端专用API
}
  1. 微服务间调用
@Configuration
public class InternalCorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/internal/**")
               .allowedOrigins("https://service1.example.com", "https://service2.example.com")
               .allowedHeaders("*")
               .allowCredentials(true);
    }
}
  1. 公共API
@CrossOrigin(origins = "*", methods = RequestMethod.GET)
@RestController
@RequestMapping("/public-api")
public class PublicApiController {
    // 开放给第三方使用的API
}

根据项目需求选择合适的配置方式,通常建议在大型项目中使用全局配置结合局部注解的方式,既能保证统一的策略,又能满足特殊端点的需求。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐