上一篇
Java跨域问题如何快速解决?
- 后端开发
- 2025-07-01
- 4
在Java中解决跨域访问权限,可通过后端配置CORS实现,常用方式包括:使用
@CrossOrigin
注解、配置
WebMvcConfigurer
全局CORS规则,或创建CORS过滤器添加
Access-Control-Allow-Origin
等响应头。
Servlet过滤器(通用方案)
import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter("/*") 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", "GET, POST, PUT, DELETE, OPTIONS"); response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); response.setHeader("Access-Control-Max-Age", "3600"); // 预检请求缓存1小时 chain.doFilter(req, res); } }
适用场景:任何Java Web项目(Servlet 3.0+)
优点:无需框架支持,兼容性强
注意:生产环境建议替换为具体域名
Spring Boot注解(最简方案)
在Controller类或方法上添加@CrossOrigin
:
@RestController @CrossOrigin(origins = "https://trusted-domain.com", allowedHeaders = {"Authorization", "Content-Type"}, maxAge = 3600) public class ApiController { @GetMapping("/data") public ResponseEntity<String> getData() { return ResponseEntity.ok("跨域数据"); } }
原理:Spring自动添加CORS响应头
配置参数:
origins
:允许的域名(默认)methods
:HTTP方法(默认所有)allowCredentials
:是否允许凭证(默认true
)
全局配置(Spring Boot推荐)
import org.springframework.context.annotation.Bean; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") // 指定路径 .allowedOrigins("https://client.com") .allowedMethods("GET", "POST") .allowCredentials(true) .exposedHeaders("Custom-Header"); // 暴露自定义头 } }; } }
优势:集中管理所有API的跨域规则,避免重复注解
Nginx反向代理(架构层方案)
在Nginx配置文件中添加:
server { listen 80; server_name api.example.com; location / { proxy_pass http://localhost:8080; # 转发到Java应用 # CORS关键配置 add_header 'Access-Control-Allow-Origin' 'https://web.com'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,Content-Type'; } }
适用场景:
- 老旧系统无法修改代码
- 需要统一网关层管理跨域
Spring Security集成
当项目使用Spring Security时,需额外配置:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and() // 启用CORS支持 .csrf().disable() .authorizeRequests() .anyRequest().authenticated(); } @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(Arrays.asList("https://secure-domain.com")); config.setAllowedMethods(Arrays.asList("GET")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return source; } }
关键点:必须调用http.cors()
启用CORS,否则配置无效
跨域常见问题及解决
-
预检请求(OPTIONS)失败
- 确保服务器处理
OPTIONS
请求(Spring Boot自动处理) - 检查
Access-Control-Allow-Methods
包含实际使用的HTTP方法
- 确保服务器处理
-
携带Cookie时报错
- 设置
allowCredentials(true)
- 响应头
Access-Control-Allow-Origin
必须指定具体域名(不能为) - 前端设置
withCredentials: true
(Ajax/axios)
- 设置
-
自定义头无法识别
- 添加
Access-Control-Expose-Headers: Custom-Header
- 在
allowedHeaders
中包含该头
- 添加
最佳实践建议
- 安全性优先:生产环境禁用
Access-Control-Allow-Origin: *
,使用白名单域名 - 精细控制:根据API敏感程度分配不同权限(如公开API用,私有API限指定域)
- 减少预检请求:设置合理的
maxAge
值(如3600秒) - 监控日志:记录非规跨域请求,及时发现攻击行为
技术原理补充:跨域是浏览器的安全策略(同源策略),当前端域名(origin)与API域名不同时,浏览器会拦截响应,除非服务器返回明确的CORS头,Java解决方案的本质就是在HTTP响应中添加正确的
Access-Control-*
头信息。
引用说明:本文解决方案参考自MDN Web文档的CORS技术规范、Spring官方文档的CORS支持章节及Oracle的Servlet规范,所有代码均通过Java 11+Spring Boot 2.7实测验证。