You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Boot中如何配置Access-Control-Allow-Origin支持多域名?

解决Spring Boot中Access-Control-Allow-Origin多域名支持问题

首先得指出你代码里的一个明显错误:response.setHeader("Access-Control-Allow-Origin","abc.com","xyz.com");这行代码是无效的——HttpServletResponse.setHeader()方法只接受键和单个值两个参数,而且浏览器本身也不支持Access-Control-Allow-Origin字段设置多个域名(该字段只能是单个域名、*或者null)。

要实现多域名跨域支持,正确的思路是动态匹配请求的Origin头,返回对应的允许域名,下面给你两种可行的实现方案:


方案一:修改自定义CORS Filter实现动态匹配

你可以先维护一个允许的域名列表,然后在Filter中获取请求的Origin头,判断是否在允许列表内,再动态设置响应头:

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;
import java.util.HashSet;

public class CORSFilter implements Filter {
    // 维护允许的域名列表
    private final Set<String> allowedOrigins = new HashSet<>();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化允许的域名,可以从配置文件读取,这里硬编码示例
        allowedOrigins.add("https://abc.com");
        allowedOrigins.add("https://xyz.com");
    }

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        // 获取请求的Origin头
        String origin = request.getHeader("Origin");

        // 如果Origin在允许列表中,设置对应的响应头
        if (allowedOrigins.contains(origin)) {
            response.setHeader("Access-Control-Allow-Origin", origin);
        }

        // 其他CORS相关头设置
        response.setHeader("Cache-Control", "no-store, public, max-age=0");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Strict-Transport-Security", "max-age=63072000; includeSubDomains;");
        
        // 处理OPTIONS预检请求,避免后续业务逻辑被触发
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return;
        }

        chain.doFilter(req, res);
    }

    @Override
    public void destroy() {
        // 销毁逻辑(如果需要)
    }
}

注意:

  • 建议把允许的域名配置到application.propertiesapplication.yml中,避免硬编码,比如用@Value注入(如果将Filter交由Spring管理)。
  • 必须处理OPTIONS预检请求,否则带自定义头、PUT/DELETE这类复杂请求会失败。

方案二:使用Spring Boot自带的CORS全局配置(推荐)

Spring Boot提供了更优雅的全局CORS配置方式,不需要自定义Filter,直接实现WebMvcConfigurer即可:

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 CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 对所有路径生效
                .allowedOrigins("https://abc.com", "https://xyz.com") // 允许的域名列表
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                .allowedHeaders("*") // 允许所有请求头
                .maxAge(3600)
                .allowCredentials(true); // 如果需要携带Cookie,必须设为true,且allowedOrigins不能用*
    }
}

这种方式的优势:

  • 无需手动处理OPTIONS请求,Spring会自动完成预检逻辑。
  • 配置更简洁,支持从配置文件读取允许的域名(比如用@Value("${cors.allowed-origins}")注入逗号分隔的字符串,再转成数组)。
  • 支持更细粒度的路径匹配(比如只对/api/**路径生效)。

关键注意点

  • 如果你需要支持携带Cookie或HTTP认证信息,Access-Control-Allow-Origin不能设为*,必须指定具体域名,同时allowCredentials要设为true
  • 确保域名包含完整的协议(http/https),否则可能出现匹配失败的情况。

内容的提问来源于stack exchange,提问作者Hearaman

火山引擎 最新活动