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.properties或application.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




