# 开启跨域 (CORS)

# 方法一:使用 全局配置 来开启跨域

Spring Boot 提供了一个更简便的方式来处理跨域问题,就是通过配置类 WebMvcConfigurer 来统一设置跨域规则。

# 1. 创建一个全局跨域配置类

你可以创建一个配置类,来全局处理跨域请求:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class GlobalCorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 设置全局跨域配置
        registry.addMapping("/**")  // 允许所有接口跨域请求
                .allowedOrigins("http://localhost:3000", "http://example.com")  // 允许的来源,可以指定多个
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")  // 允许的方法
                .allowedHeaders("*")  // 允许的请求头
                .allowCredentials(true)  // 是否允许发送Cookie
                .maxAge(3600);  // 预检请求的缓存时间,单位是秒
    }
}

# 2. 配置说明

  • addMapping("/**"):表示所有的请求都允许跨域。
  • allowedOrigins(...):指定允许跨域的域名,可以设置为具体的域名或使用 * 来允许所有域名。
  • allowedMethods(...):指定允许的 HTTP 方法,例如 GET, POST, PUT, DELETE, OPTIONS 等。
  • allowedHeaders("*"):允许所有的请求头,可以指定特定的请求头。
  • allowCredentials(true):表示是否允许客户端发送 cookie。默认为 false
  • maxAge(3600):设置预检请求的有效期,单位为秒。

# 方法二:使用 @CrossOrigin 注解来指定特定接口

如果你仅想针对某些接口启用跨域,可以继续使用 @CrossOrigin 注解,只不过这样就不用在每个方法上加,而是在类上加。

# 1. 示例:针对类进行跨域配置

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;

@CrossOrigin(origins = "http://localhost:3000")  // 全局应用跨域
@RestController
public class MyController {

    @GetMapping("/data")
    public String getData() {
        return "This is data!";
    }
}

# 2. 示例:针对方法进行跨域配置

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;

@RestController
public class MyController {

    @CrossOrigin(origins = "http://localhost:3000")  // 单独方法应用跨域
    @GetMapping("/data")
    public String getData() {
        return "This is data!";
    }
}

# 方法三:使用 Filter 来处理跨域

如果你需要更细粒度的控制,也可以通过创建一个 Filter 来处理跨域。

# 1. 创建一个跨域过滤器

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter("/*")  // 所有请求都会经过这个 Filter
public class CorsFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化时可以做一些配置
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        
        // 设置跨域头信息
        httpResponse.setHeader("Access-Control-Allow-Origin", "*");  // 允许所有来源跨域
        httpResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");  // 允许的方法
        httpResponse.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");  // 允许的请求头
        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");  // 是否允许发送cookie
        
        chain.doFilter(request, response);  // 继续执行后续的过滤器或处理器
    }

    @Override
    public void destroy() {
        // 销毁时可以做一些资源释放
    }
}

# 2. 启动时注册过滤器

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<CorsFilter> corsFilter() {
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new CorsFilter());
        bean.addUrlPatterns("/api/*");  // 设置过滤器作用的 URL
        return bean;
    }
}

# 总结:

  1. 全局配置 CORS:最推荐的方式,统一配置,不需要在每个 Controller 上加注解。
  2. Controller 层注解:适合有些接口需要单独处理跨域的场景。
  3. Filter 过滤器:适合更复杂的跨域控制需求。
Last Updated: 9/18/2025, 12:45:33 PM