精心整理了最新的面试资料和简历模板,有需要的可以自行获取
一、跨域问题的本质
1.1 什么是跨域?
跨域(Cross-Origin)问题源于浏览器的同源策略(Same-Origin Policy),该策略限制了一个源的文档或脚本如何与另一个源的资源进行交互。当协议(http/https)、域名或端口任意一项不同时,即被视为跨域请求。
1.2 CORS 工作机制
CORS(Cross-Origin Resource Sharing)是现代浏览器支持的标准机制,通过特定的HTTP头来实现跨域访问控制。其核心流程包括:
- 简单请求 :直接发送请求,携带
Origin
头 - 预检请求(Preflight):对非简单请求先发送OPTIONS请求验证
- 凭证请求:携带Cookie等认证信息时需要特殊处理
二、Spring Boot 解决方案大全
2.1 注解方案:@CrossOrigin
最快捷的局部解决方案,适用于单个控制器方法或类
java
@RestController
@CrossOrigin(origins = "http://localhost:8080",
maxAge = 3600,
allowedHeaders = "*",
methods = {RequestMethod.GET, RequestMethod.POST})
public class ApiController {
@CrossOrigin // 允许所有源
@GetMapping("/data")
public ResponseEntity<?> getData() {
// ...
}
}
2.2 全局配置方案(推荐)
通过实现WebMvcConfigurer
进行统一配置
java
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://trusted-domain.com")
.allowedMethods("GET", "POST", "PUT")
.allowCredentials(true)
.maxAge(1800);
}
}
2.3 过滤器方案
适用于需要细粒度控制的场景
java
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("https://*.example.com");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
2.4 Spring Security 集成方案
当项目使用Spring Security时需要额外配置
java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().configurationSource(request -> {
CorsConfiguration config = new CorsConfiguration();
config.applyPermitDefaultValues();
config.addAllowedMethod(HttpMethod.PUT);
return config;
});
// 其他安全配置...
}
}
三、进阶配置与最佳实践
3.1 动态源配置
根据环境动态设置允许的源
yaml
# application.yml
cors:
allowed-origins:
- "http://localhost:8080"
- "https://prod-domain.com"
java
@Value("${cors.allowed-origins}")
private String[] allowedOrigins;
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins(allowedOrigins);
}
3.2 预检请求缓存优化
通过Access-Control-Max-Age
头减少OPTIONS请求次数
java
config.setMaxAge(3600L); // 单位:秒
3.3 安全增强措施
java
// 明确指定允许的Header
config.setAllowedHeaders(Arrays.asList(
"Content-Type",
"Authorization",
"X-Requested-With"
));
// 禁用危险配置
config.setAllowCredentials(false); // 除非必要
config.setAllowedOrigins(List.of("https://specific-domain.com")); // 避免使用*
四、常见问题排查指南
4.1 配置未生效的检查清单
- 配置类是否被
@Configuration
注解 - 过滤器顺序是否正确(建议优先级高于认证过滤器)
- Spring Security是否覆盖了CORS配置
- 是否有多余的CORS配置相互覆盖
4.2 浏览器控制台错误解析
- 403 Forbidden:检查Spring Security配置
- Missing CORS headers:确认服务器正确返回CORS头
- Preflight失败:确保OPTIONS请求被正确处理
4.3 生产环境推荐配置
java
// 生产环境配置示例
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(List.of("https://production-domain.com"));
config.setAllowedMethods(List.of("GET", "POST"));
config.setAllowedHeaders(List.of("Authorization", "Content-Type"));
config.setExposedHeaders(List.of("X-Custom-Header"));
config.setMaxAge(1800L);
config.setAllowCredentials(true);
五、架构层面的解决方案
5.1 API 网关统一处理
通过Nginx配置反向代理解决跨域:
nginx
location /api {
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://backend-service;
}
5.2 微服务架构中的跨域方案
- 网关层统一处理CORS
- 各服务禁用CORS配置
- 使用JWT等Token验证替代Cookie
六、扩展知识:现代浏览器的CORS策略
特性 | Chrome | Firefox | Safari |
---|---|---|---|
预检请求缓存 | 支持 | 支持 | 部分 |
通配符子域 | 支持 | 支持 | 限制 |
Credentials跨域 | 严格 | 严格 | 严格 |
私有网络访问(Localhost) | 特殊处理 | 特殊处理 | 限制 |
结语
正确配置CORS需要平衡功能需求与安全性。建议遵循最小权限原则,生产环境避免使用通配符(*),定期审查CORS配置。随着Spring框架的迭代更新(当前最新6.x版本),建议关注官方文档获取最新最佳实践。