当前位置:首页 > 后端开发 > 正文

Java跨域问题如何快速解决?

在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的跨域规则,避免重复注解

Java跨域问题如何快速解决?  第1张


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,否则配置无效


跨域常见问题及解决

  1. 预检请求(OPTIONS)失败

    • 确保服务器处理OPTIONS请求(Spring Boot自动处理)
    • 检查Access-Control-Allow-Methods包含实际使用的HTTP方法
  2. 携带Cookie时报错

    • 设置allowCredentials(true)
    • 响应头Access-Control-Allow-Origin必须指定具体域名(不能为)
    • 前端设置withCredentials: true(Ajax/axios)
  3. 自定义头无法识别

    • 添加Access-Control-Expose-Headers: Custom-Header
    • allowedHeaders中包含该头

最佳实践建议

  1. 安全性优先:生产环境禁用Access-Control-Allow-Origin: *,使用白名单域名
  2. 精细控制:根据API敏感程度分配不同权限(如公开API用,私有API限指定域)
  3. 减少预检请求:设置合理的maxAge值(如3600秒)
  4. 监控日志:记录非规跨域请求,及时发现攻击行为

技术原理补充:跨域是浏览器的安全策略(同源策略),当前端域名(origin)与API域名不同时,浏览器会拦截响应,除非服务器返回明确的CORS头,Java解决方案的本质就是在HTTP响应中添加正确的Access-Control-*头信息。


引用说明:本文解决方案参考自MDN Web文档的CORS技术规范、Spring官方文档的CORS支持章节及Oracle的Servlet规范,所有代码均通过Java 11+Spring Boot 2.7实测验证。

0