Spring Boot 配置跨域(CORS)详解
在前后端分离项目中,经常会遇到跨域问题。例如:
Access to XMLHttpRequest at 'https://api.blog.gs/login' from origin 'https://blog.gs'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
浏览器安全策略会限制 不同域名/端口/协议 之间的请求,这就是所谓的 同源策略。而 CORS(跨域资源共享,Cross-Origin Resource Sharing)就是为了解决这个问题。
一、常见跨域场景
- 前端部署在
https://blog.gs
- 后端 API 部署在
https://api.blog.gs
此时,前端调用后端 API 就会触发跨域。
二、Spring Boot 配置跨域(无 Security)
如果项目中没有使用 Spring Security,只需要实现 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://blog.gs") // 指定允许的前端域名
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true) // 是否允许携带 Cookie、Authorization 等凭证
.maxAge(3600); // 预检请求缓存时间(秒)
}
}
注意事项
- 如果使用
allowedOrigins("*")
,不能再设置allowCredentials(true)
,否则无效。 - 生产环境推荐指定具体域名,而不是
"*"
。
三、Spring Boot 配置跨域(有 Security)
如果项目使用了 Spring Security,那么上面的 CorsConfig
不会生效,必须在 Security 配置中显式开启 CORS。
示例代码:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.List;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().disable()
.csrf().disable()
.cors() // ✅ 开启跨域
.and()
.authorizeRequests()
.antMatchers("/admin/**").authenticated()
.anyRequest().permitAll()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
// ✅ 提供 CORS 配置
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("https://blog.gs")); // 指定前端域名
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Bean
@Override
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}
四、如何验证 CORS 是否生效?
- 浏览器 F12 → Network 面板
- 发起 API 请求
- 查看 Response Headers 是否包含:
Access-Control-Allow-Origin: https://blog.gs
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
如果有这些头部,说明 CORS 配置成功。
五、总结
- 无 Security 项目:实现
WebMvcConfigurer
即可。 - 有 Security 项目:必须在
HttpSecurity
里启用.cors()
,并提供CorsConfigurationSource
Bean。 - 生产环境:推荐指定固定域名,而不是
"*"
,以提升安全性。
这样配置后,前端就可以正常请求后端接口,不再被浏览器拦截。