You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署后Spring Boot应用如何绕过CORS策略?多种尝试均失败

Spring Boot 3 + Angular 15 CORS问题求助

我开发了一个小型网站,采用Spring Boot 3作为后端、Angular 15作为前端,目前遇到CORS问题,前端无法与后端通信。查阅大量资料并尝试多种方案均未成功。

已尝试的解决方案

尝试1:在Security Config中添加CORS配置Bean

@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("*"));
    configuration.setAllowedHeaders(List.of("*"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

尝试2:在Security Config中添加另一个CORS配置Bean

@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("*"));
    configuration.setAllowCredentials(true);
    // 添加相关CORS响应头
    configuration.addAllowedOrigin("*");
    configuration.addAllowedHeader("*");
    configuration.addAllowedMethod("*");
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

尝试3:为控制器类添加@CrossOrigin注解

import org.springframework.web.bind.annotation.CrossOrigin;

@RestController
@RequestMapping("/api/v1/productcategory")
@CrossOrigin
public class ProductCategoryController {

    @Autowired
    ProductCategoryService productCategoryService;
    
    @GetMapping
    public ResponseEntity<List<ProductCategory>> get(){
        return ResponseEntity.ok(productCategoryService.getAll());
    }
    @PostMapping
    public ResponseEntity<String> post(){
        return ResponseEntity.ok("POST: Hello Management");
    }
    @PutMapping
    public ResponseEntity<String> put(){
        return ResponseEntity.ok("PUT: Hello Management");
    }
    @DeleteMapping
    public ResponseEntity<String> delete(){
        return ResponseEntity.ok("DELETE: Hello Management");
    }
}

尝试4:在FilterChain中手动添加CORS响应头

@Override
protected void doFilterInternal(@NonNull HttpServletRequest request, 
                                @NonNull HttpServletResponse response, 
                                @NonNull FilterChain filterChain) throws ServletException, IOException {
    
    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
    
    final String authHeader = request.getHeader("Authorization");
    final String jwt;
    final String userEmail;
    
    if(authHeader == null || !authHeader.startsWith("Bearer ")) {
        filterChain.doFilter(request, response);
        return;
    }
    jwt = authHeader.substring(7);
    userEmail = jwtService.extractUsername(jwt);

    if(userEmail !=null && SecurityContextHolder.getContext().getAuthentication() == null) {
        UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail);
        var isTokenValid = tokenRepository.findByToken(jwt)
                                            .map(t -> !t.isExpired() && !t.isRevoked())
                                            .orElse(false);
        if(jwtService.isTokenValid(jwt, userDetails) && isTokenValid) {
            UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authToken);
        }
    }
    filterChain.doFilter(request, response);
}

补充说明

后端使用JWT令牌进行身份验证和授权。

Angular端配置的HttpInterceptor

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpResponse,
  HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class RequestInterceptorInterceptor implements HttpInterceptor {

  constructor() {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    if (request.method !== 'OPTIONS') {
      const jwtString = localStorage.getItem('jwt');
      const jwtToken = jwtString ? JSON.parse(jwtString)?.jwt as string : '';
      const authorizationHeader = `Bearer ${jwtToken}`;
      request = request.clone({ headers: request.headers.set('Authorization', authorizationHeader)});
    }

    return next.handle(request).pipe(
      catchError((error: HttpErrorResponse) => {
        // 捕获错误并执行相应操作
        if (error.status === 0 && error.statusText === 'Unknown Error') {
          console.log('Es ist ein CORS-Fehler aufgetreten');
          // 执行更多操作...
        }

        // 将错误继续抛出,传递给调用者
        return throwError(error);
      })
    );
  }
}

错误日志截图

错误日志截图

所有尝试都无法通过预检请求,请问哪里出错了?还有什么可尝试的方法能让前后端正常通信?


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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 21:00:06