Angular前端调用Java Spring后端时跨域请求被拦截问题
跨域请求被阻止问题排查与解决
核心问题分析
Postman调用API正常,但浏览器跨域报错,说明后端API逻辑没问题,问题出在CORS配置未正确处理浏览器的预检请求。浏览器发送带Content-Type: application/json的跨域POST请求时,会先发送OPTIONS预检请求,验证后端是否允许该跨域操作,若后端未配置允许OPTIONS方法,就会触发跨域拦截。
解决方案
1. 修正Spring CORS配置,允许OPTIONS方法
你的CORS配置中仅允许了GET/POST/DELETE,缺少浏览器预检必需的OPTIONS方法,修改如下:
@Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(List.of("http://localhost:4200")); // 添加OPTIONS方法,支持预检请求 configuration.setAllowedMethods(List.of("GET", "POST", "DELETE", "OPTIONS")); configuration.setAllowedHeaders(List.of("Authorization", "Content-Type")); // 允许携带凭证(如登录后的token,根据需求开启) configuration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; }
2. 确保Spring Security启用CORS
仅定义CorsConfigurationSource Bean不够,需要在Security过滤链中显式启用CORS,让Spring Security处理预检请求:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 启用CORS,需放在csrf配置前 .cors(cors -> cors.configurationSource(corsConfigurationSource())) .csrf(csrf -> csrf.disable()) // 跨域场景下通常关闭CSRF,或根据需求配置 .authorizeHttpRequests(auth -> auth // 开放认证相关接口无需权限 .requestMatchers("/auth/**").permitAll() .anyRequest().authenticated() ); return http.build(); }
3. 确保Angular请求头正确设置
你的AuthService中注释掉了Content-Type设置,虽然HttpClient默认会为JSON请求添加该头,但显式设置可避免潜在问题:
// 修改headers初始化 headers = new HttpHeaders().set('Content-Type', 'application/json'); // 在请求中使用该headers signUp(input: ClientRegistrationInput): Observable<any> { let api = `${this.endpoint}/auth/signup-customer`; return this.http.post(api, input, { headers: this.headers }).pipe(catchError(this.handleError)); } signIn(loginInput: LoginInput) { return this.http .post<any>(`${this.endpoint}/auth/login`, loginInput, { headers: this.headers }) .subscribe((res: any) => { localStorage.setItem('access_token', res.token); this.getUserProfile(res.utilisateurId).subscribe((res) => { this.currentUser = res; this.router.navigate(['user-profile/' + res.utilisateurId]); }); }); }
验证
修改后重启前后端,再次提交表单,浏览器的OPTIONS预检请求会被后端正确响应,跨域POST请求即可正常执行。
内容的提问来源于stack exchange,提问作者Henry2025
相关产品推荐
相关产品推荐

