文章目录
- 一、引言:跨域问题的本质与解决方案分类
- 解决方案分类
- 二、方案一:`WebMvcConfigurer` 全局配置(推荐)
- 1. 核心代码(你提供的 `CorsConfig` 示例)
- 2. 代码详解
- 3. 优点
- 4. 注意事项
- 三、方案二:`CorsFilter` 过滤器配置(传统方式)
- 1. 核心代码(你提供的 `ResourcesConfig` 示例)
- 2. 代码详解
- 3. 优点
- 4. 注意事项
- 四、方案三:`@CrossOrigin` 注解配置(局部控制)
- 1. 核心代码
- 2. 代码详解
- 3. 优点
- 4. 缺点
- 五、三种方案的对比与选择建议
- 六、安全最佳实践
- 1. 禁用危险组合
- 2. 细化允许的 Header 和 Method
- 3. HTTPS 强制要求
- 4. 预检请求(OPTIONS)处理
- 七、附录:完整配置示例(结合三种方案)
- 1. `WebMvcConfigurer` 分层配置
- 2. `CorsFilter` 过滤器配置
- 3. `@CrossOrigin` 注解配置
一、引言:跨域问题的本质与解决方案分类
在前后端分离开发中,跨域问题是开发者必须面对的核心挑战之一。浏览器的同源策略(Same-Origin Policy)会拦截不同协议(HTTP/HTTPS)、不同域名或不同端口的请求,导致如下错误:
Access to fetch at 'http://api.example.com' from origin 'http://localhost:3000' has been blocked by CORS policy.
解决方案分类
- 注解配置:通过
@CrossOrigin
注解实现局部接口的跨域控制。 - 全局配置:通过
WebMvcConfigurer
统一管理所有接口的跨域规则。 - 过滤器配置:通过
CorsFilter
实现基于 Servlet 的低层跨域控制。
本文将结合你提供的两个代码片段(CorsConfig
和 ResourcesConfig
),深入解析其原理,并补充第三种方案(@CrossOrigin
注解),帮助你全面掌握跨域问题的解决方案。
二、方案一:WebMvcConfigurer
全局配置(推荐)
1. 核心代码(你提供的 CorsConfig
示例)
@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOriginPatterns("*").allowCredentials(true).allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH").maxAge(3600);}
}
2. 代码详解
addMapping("/**")
对所有路径(/**
)启用跨域配置。allowedOriginPatterns("*")
允许任意域名访问(通配符*
)。注意:若启用allowCredentials(true)
,必须明确指定域名,不能使用*
。allowCredentials(true)
允许客户端携带 Cookie 或 Token 等凭证(需与allowedOrigins
严格匹配,否则会引发安全漏洞)。allowedMethods(...)
明确允许的 HTTP 方法(如 GET、POST 等)。maxAge(3600)
预检请求(OPTIONS)的缓存时间,单位为秒(3600 = 1小时)。
3. 优点
- 集中管理:统一配置所有接口的跨域规则。
- 路径分层控制:支持对不同路径设置不同策略(如
/public/**
允许所有来源,/private/**
限制来源)。 - Spring MVC 原生支持:与 Spring Boot 深度集成,无需额外依赖。
4. 注意事项
- 避免
allowedOriginPatterns("*") + allowCredentials(true)
:此组合可能导致 CSRF 攻击。 - 版本兼容性:
allowedOriginPatterns(...)
是 Spring 5.3+ 引入的方法,低版本需改用allowedOrigins(...)
。
三、方案二:CorsFilter
过滤器配置(传统方式)
1. 核心代码(你提供的 ResourcesConfig
示例)
@Configuration
public class ResourcesConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 资源映射配置(可选)}/*** 跨域配置*/@Beanpublic CorsFilter corsFilter(