java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot项目解决跨域

SpringBoot项目解决跨域的5种实现过程

作者:油墨香^_^

本文介绍了SpringBoot项目中解决跨域问题的5种方式,包括使用@CrossOrigin注解、全局配置WebMvcConfigurer、使用CorsFilter过滤器、WebFlux配置和手动配置过滤器,推荐使用全局配置WebMvcConfigurer,因为它既统一又灵活,适合大多数项目场景

在SpringBoot项目中,解决跨域问题主要有以下5种方式:

1. 使用@CrossOrigin注解

在Controller类或方法上添加注解

// 在类级别使用 - 该类所有接口都支持跨域
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/api")
public class UserController {
    // 在方法级别使用 - 仅此方法支持跨域
    @CrossOrigin(origins = "http://localhost:3000")
    @GetMapping("/users")
    public List<User> getUsers() {
        return userService.findAll();
    }
    @PostMapping("/users")
    public User createUser(@RequestBody User user) {
        return userService.save(user);
    }
}

@CrossOrigin参数说明

@CrossOrigin(
    origins = "*",                    // 允许的源
    allowedHeaders = "*",             // 允许的请求头
    methods = {RequestMethod.GET, RequestMethod.POST}, // 允许的HTTP方法
    allowCredentials = "true",        // 是否允许证书
    maxAge = 3600                     // 预检请求缓存时间
)

2. 全局配置 - 实现WebMvcConfigurer

方式一:配置类方式

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")  // 对所有接口路径
                .allowedOriginPatterns("*")  // 支持域匹配,SpringBoot 2.4+
                // .allowedOrigins("*")      // SpringBoot 2.4之前版本使用
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

方式二:配置文件方式

# application.yml
spring:
  mvc:
    cors:
      allowed-origins: "*"
      allowed-methods: GET,POST,PUT,DELETE,OPTIONS
      allowed-headers: "*"
      allow-credentials: true
      max-age: 3600

3. 使用CorsFilter过滤器

@Configuration
public class GlobalCorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        // 1. 创建CORS配置对象
        CorsConfiguration config = new CorsConfiguration();
        // 2. 配置CORS规则
        config.addAllowedOriginPattern("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        config.setAllowCredentials(true);
        config.setMaxAge(3600L);
        // 3. 添加映射路径
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

4. 使用WebFlux配置(响应式编程)

如果使用WebFlux,可以这样配置:

@Configuration
public class CorsWebFluxConfig {
    @Bean
    public CorsWebFilter corsWebFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOriginPattern("*");
        config.addAllowedMethod("*");
        config.addAllowedHeader("*");
        config.setAllowCredentials(true);
        config.setMaxAge(3600L);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}

5. 手动配置过滤器

@Component
public class SimpleCorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        // 设置CORS头部
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        // 处理预检请求
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }
    @Override
    public void init(FilterConfig filterConfig) {}
    @Override
    public void destroy() {}
}

生产环境推荐配置

@Configuration
public class ProductionCorsConfig implements WebMvcConfigurer {
    @Value("${cors.allowed-origins:*}")
    private String[] allowedOrigins;
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOriginPatterns(allowedOrigins)
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("Authorization", "Content-Type", "X-Requested-With")
                .exposedHeaders("X-Custom-Header")
                .allowCredentials(true)
                .maxAge(1800); // 30分钟
        // 管理接口特殊配置
        registry.addMapping("/admin/**")
                .allowedOriginPatterns("https://admin.example.com")
                .allowedMethods("GET", "POST")
                .allowCredentials(true);
    }
}

配置说明文件

# application-prod.yml
cors:
  allowed-origins: 
    - "https://www.example.com"
    - "https://api.example.com"

总结对比

方式适用场景优点缺点
@CrossOrigin单个接口或控制器精确控制,简单易用重复配置,不够统一
WebMvcConfigurer全局配置统一管理,配置灵活需要创建配置类
CorsFilter过滤器级别处理更底层,性能较好配置相对复杂
WebFlux配置响应式应用专为WebFlux设计仅适用于响应式
手动过滤器完全自定义最大灵活性需要手动处理所有细节

推荐使用全局配置(WebMvcConfigurer),因为它既统一又灵活,适合大多数项目场景。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文