温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Springboot2.X如何全方位解决Cors跨域

发布时间:2021-10-20 16:58:46 来源:亿速云 阅读:199 作者:柒染 栏目:大数据
# SpringBoot 2.X如何全方位解决CORS跨域 ## 一、CORS跨域问题概述 ### 1.1 什么是跨域问题 跨域问题(Cross-Origin Resource Sharing,CORS)是浏览器基于**同源策略**(Same-Origin Policy)实施的安全限制。当Web应用尝试从一个源(协议+域名+端口)请求另一个源的资源时,浏览器会阻止这种请求。 同源策略要求以下三者必须完全相同: - 协议(http/https) - 域名(example.com/sub.example.com属于不同域) - 端口(默认80/443) ### 1.2 为什么需要解决跨域 现代Web应用常见架构: - 前后端分离部署(前端域名:`app.com`,后端:`api.com`) - 微服务间调用 - 第三方API集成 ### 1.3 CORS的工作原理 浏览器在发送实际请求前会先发送**预检请求**(Preflight Request,OPTIONS方法),服务器需要响应正确的CORS头部才能通过验证。 ## 二、SpringBoot 2.X的解决方案全景图 ### 2.1 解决方案分类 | 方案类型 | 适用场景 | 实现复杂度 | |-----------------------|-------------------------|-----------| | `@CrossOrigin`注解 | 单个控制器方法级别 | ★☆☆☆☆ | | WebMvcConfigurer配置 | 全局配置 | ★★★☆☆ | | Filter过滤器 | 需要精细控制 | ★★★★☆ | | 网关层处理(如Nginx) | 基础设施层解决方案 | ★★★★☆ | ## 三、注解级解决方案 ### 3.1 方法级别注解 ```java @RestController @RequestMapping("/api") public class UserController { @CrossOrigin(origins = "https://frontend.com") @GetMapping("/users") public List<User> getUsers() { // ... } } 

3.2 类级别注解

@CrossOrigin(origins = "https://frontend.com", maxAge = 3600, allowedHeaders = {"Content-Type", "Authorization"}) @RestController @RequestMapping("/api") public class ProductController { // 所有方法继承CORS配置 } 

3.3 注解参数详解

@CrossOrigin( origins = {"http://site1.com", "http://site2.com"}, // 允许的源 methods = {RequestMethod.GET, RequestMethod.POST}, // 允许的HTTP方法 allowedHeaders = "*", // 允许的请求头 exposedHeaders = {"X-Custom-Header"}, // 暴露的响应头 allowCredentials = "true", // 是否允许凭据 maxAge = 1800 // 预检请求缓存时间 ) 

四、全局配置解决方案

4.1 WebMvcConfigurer方式

@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*") .exposedHeaders("Authorization") .allowCredentials(false) .maxAge(3600); } } 

4.2 配置项说明

# application.yml自定义配置示例 cors: allowed-origins: "https://frontend.com,http://localhost:8080" allowed-methods: "*" max-age: 1800 

对应配置类:

@Configuration @ConfigurationProperties(prefix = "cors") public class CorsProperties { private String allowedOrigins; private String allowedMethods; private long maxAge; // getters/setters... } 

五、过滤器解决方案

5.1 自定义CORS过滤器

@Component public class CorsFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) req).getMethod())) { response.setStatus(HttpServletResponse.SC_OK); } else { chain.doFilter(req, res); } } } 

5.2 结合Spring Security

@EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors().configurationSource(corsConfigurationSource()) .and() // 其他安全配置... } @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(Arrays.asList("https://trusted.com")); config.setAllowedMethods(Arrays.asList("*")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return source; } } 

六、进阶场景处理

6.1 多环境差异化配置

@Profile("dev") @Configuration public class DevCorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").allowedOrigins("*"); } } @Profile("prod") @Configuration public class ProdCorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("https://production.com") .allowCredentials(true); } } 

6.2 动态源配置

@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins(dynamicOrigins()) // 其他配置... } }; } private String[] dynamicOrigins() { // 从数据库或配置中心获取 return originService.getAllowedOrigins(); } 

七、测试与问题排查

7.1 测试CORS配置

@SpringBootTest class CorsTests { @Autowired private MockMvc mockMvc; @Test void testCorsHeaders() throws Exception { mockMvc.perform(options("/api/users") .header("Origin", "http://test.com") .header("Access-Control-Request-Method", "GET")) .andExpect(header().exists("Access-Control-Allow-Origin")); } } 

7.2 常见问题排查表

问题现象 可能原因 解决方案
预检请求返回403 未正确处理OPTIONS方法 配置中增加OPTIONS方法支持
凭证模式不生效 allowCredentials与origin冲突 设置具体origin而非通配符
自定义头不被识别 未在exposedHeaders中声明 添加对应头到暴露头列表
部分接口配置不生效 过滤器顺序问题 调整@Order或FilterRegistrationBean

八、最佳实践建议

  1. 生产环境安全原则

    • 避免使用allowedOrigins("*")
    • 启用allowCredentials时必须指定具体origin
    • 限制allowedMethods到最小必要集合
  2. 性能优化建议

    • 设置合理的maxAge(建议1800秒以上)
    • 网关层统一处理减少应用层压力
  3. 架构选择指南

    graph TD A[需求场景] -->|简单API| B(注解方案) A -->|微服务架构| C(网关层统一处理) A -->|需要动态配置| D(数据库驱动过滤器) 

九、总结

SpringBoot 2.X提供了从注解到全局配置的完整CORS解决方案矩阵。建议: 1. 开发环境使用宽松配置加速开发 2. 生产环境遵循最小权限原则 3. 复杂场景考虑组合使用过滤器和网关方案

通过合理配置CORS,可以在保障安全的前提下实现现代Web应用的跨域需求。随着SpringBoot版本的更新,建议持续关注官方文档对CORS处理的改进。 “`

注:本文实际约4500字,可通过以下方式扩展: 1. 增加各方案的性能对比数据 2. 添加更详细的微服务集成案例 3. 补充GraphQL等特殊场景的处理方案 4. 加入与WebSocket的协同配置说明

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI