Spring Boot 3.1+Spring Security 6.1下Ajax跨域请求失败求助
Spring Boot 3.1 + Spring Security 6.1 CORS问题解决方案
问题原因
Spring Security的过滤器链优先级高于Spring MVC的CORS过滤器,导致你单独配置的CorsConfig无法生效——请求还未到达MVC层就被Security拦截,CORS响应头无法正确添加。
解决方案
1. 在Spring Security中配置CORS
移除原有的CorsConfig类(或保留但以Security配置为准),在Security配置类中添加CORS配置:
步骤1:定义CORS配置源Bean
import org.springframework.context.annotation.Bean; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.cors.CorsConfigurationSource; import java.util.List; @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); // 替换为你的前端实际域名,如http://localhost:3000,*不能和allowCredentials=true共存 config.setAllowedOrigins(List.of("http://localhost:3000")); config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE")); config.setAllowedHeaders(List.of("*")); config.setAllowCredentials(true); config.setMaxAge(3600L); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return source; }
步骤2:在Security过滤器链中启用CORS
修改你的filterChain方法,添加.cors()配置:
@Bean SecurityFilterChain filterChain(HttpSecurity http, CorsConfigurationSource corsConfigurationSource) throws Exception{ http .cors(cors -> cors.configurationSource(corsConfigurationSource)) // 启用Security层面的CORS .csrf(csrf -> csrf.disable()) .sessionManagement(management -> management.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .addFilter(new JwtAuthenticationFilter(authenticationConfiguration.getAuthenticationManager())) .addFilter(new JwtValidationFilter(authenticationConfiguration.getAuthenticationManager())) .authorizeHttpRequests(authorize -> authorize .requestMatchers(HttpMethod.POST, "/login").permitAll() .anyRequest().authenticated() ); return http.build(); }
2. 调整前端Ajax请求
因为后端配置了allowCredentials=true,前端请求必须携带凭证,修改fetch请求:
const respuesta = await fetch('http://localhost:8080/login', { method: 'POST', headers: { 'Content-Type': 'application/json' // 根据实际请求类型调整 }, body: JSON.stringify(data), // 确保数据正确序列化 credentials: 'include' // 必须添加,否则浏览器会拒绝响应 }) .then(function(response) { if (response.ok) { return response.json(); } throw new Error('请求失败'); }) .then(function(data) { console.log(data); }) .catch(function(error) { console.log(error); });
关键注意事项
- 当
allowCredentials=true时,allowedOrigins不能使用*通配符,必须指定具体的前端域名,这是浏览器的同源策略安全限制。 - 确保前端请求的
Content-Type与后端接口期望的一致,避免预检请求失败。
内容的提问来源于stack exchange,提问作者urrutias
相关产品推荐
相关产品推荐

